Image generated with Chatgpt
Table of Contents¶
- Project NoSQL
- Dogs & Cats Database
- API & NoSQL Project: Cat and Dog Data
- NoSQL Schema Description ā Pets DB
- Collections Creations
- Transformation
- Data Analysis
- Dogs Database Collection
- Intelligent Dog Breeds in the Sporting Group
- Filtered List of Intelligent Sporting Breeds
- Top 10 Tallest Dog Breeds
- Average Metric Weight by Dog Breed
- Longevity Analysis of Dog Breeds
- Breed Group Distribution
- Cat Breeds by Geographic Origin
- Origin Distribution of Cat Breeds
- Top 10 Longest-Living Cat and Dog Breeds
- Conclusion
- Learning
š¾ API & NoSQL Project: Cat and Dog Data¶
This beginner-friendly project connects to a public API to collect data on cats and dogs, including:
- š¶ Breed names
- š§ Temperament traits
- 𧬠Other characteristics
The data is stored in a MongoDB NoSQL database.
š” Key Concepts¶
- API requests and JSON handling
- NoSQL data modeling with MongoDB
- Aggregation and querying unstructured data
š Outcome¶
Build a solid foundation in API integration and NoSQL storage, essential for backend and data-driven applications.
Requirements & Configuration
import pymongo
import pprint as pp
import pandas as pd
import requests
import json
import time
import string
import re
import matplotlib.pyplot as plt
import numpy as np
# API and Database details
API_URL_1 = "https://api.thedogapi.com/v1/breeds"
API_URL_2 = "https://api.thecatapi.com/v1/breeds"
DOG_API_KEY = "live_zxfLgASbdmoVWuJ3PZSm5dUrrsuoaJMV0YnoCVlporMq4ijHVnQpkiZQXegC8BYv"
CAT_API_KEY = "live_MEzvYHLqnt7f6Wi1URvxHttSq8MFuh2s0fLZTAVsqJ1IGZRA0R8eUknafoFDm0Xc"
CNX_STR = "localhost:27017"
DB_NAME_1 = "dogsdb"
DB_NAME_2 = "catsdb"
DB_NAME_3 = "petsdb"
COLL_NAME_1 = "type_dogs"
COLL_NAME_2 = "type_cats"
COLL_NAME_3 = "type_pets"
ELT Process DB Setup
# connection to MongoDB
client = pymongo.MongoClient(CNX_STR)
#dogs database
db_1 = client[DB_NAME_1]
dogs = db_1[COLL_NAME_1]
#cats databse
db_2 = client[DB_NAME_2]
cats = db_2[COLL_NAME_2]
#Pets Database
db_3 = client[DB_NAME_3]
pets = db_3[COLL_NAME_3]
# Remove all existing collection
cats.drop()
dogs.drop()
pets.drop()
client.drop_database("petsdb")
client.drop_database("catsdb")
client.drop_database("dog_database")
client.drop_database("cat_database")
Extract & find a document
# download all dog breeds
url = f'{API_URL_1}?f='
headers = {"x-api-key": DOG_API_KEY}
response = requests.get(url, headers=0)
dog = response.json()
# inspect first dog
sample_dog = dog[0] # This accesses the first element in the list.
pp.pprint(sample_dog)
{'bred_for': 'Small rodent hunting, lapdog',
'breed_group': 'Toy',
'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
'id': 1,
'life_span': '10 - 12 years',
'name': 'Affenpinscher',
'origin': 'Germany, France',
'reference_image_id': 'BJa4kxc4X',
'temperament': 'Stubborn, Curious, Playful, Adventurous, Active, Fun-loving',
'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
# download all cat breeds
url = f'{API_URL_2}?f='
headers = {"x-api-key": CAT_API_KEY}
response = requests.get(url, headers=0)
cat = response.json()
# inspect first cat
sample_cat = cat[0] # This accesses the first element in the list.
pp.pprint(sample_cat)
{'adaptability': 5,
'affection_level': 5,
'alt_names': '',
'cfa_url': 'http://cfa.org/Breeds/BreedsAB/Abyssinian.aspx',
'child_friendly': 3,
'country_code': 'EG',
'country_codes': 'EG',
'description': 'The Abyssinian is easy to care for, and a joy to have in your '
'home. Theyāre affectionate cats and love both people and '
'other animals.',
'dog_friendly': 4,
'energy_level': 5,
'experimental': 0,
'grooming': 1,
'hairless': 0,
'health_issues': 2,
'hypoallergenic': 0,
'id': 'abys',
'indoor': 0,
'intelligence': 5,
'lap': 1,
'life_span': '14 - 15',
'name': 'Abyssinian',
'natural': 1,
'origin': 'Egypt',
'rare': 0,
'reference_image_id': '0XYvRd7oD',
'rex': 0,
'shedding_level': 2,
'short_legs': 0,
'social_needs': 5,
'stranger_friendly': 5,
'suppressed_tail': 0,
'temperament': 'Active, Energetic, Independent, Intelligent, Gentle',
'vcahospitals_url': 'https://vcahospitals.com/know-your-pet/cat-breeds/abyssinian',
'vetstreet_url': 'http://www.vetstreet.com/cats/abyssinian',
'vocalisation': 1,
'weight': {'imperial': '7 - 10', 'metric': '3 - 5'},
'wikipedia_url': 'https://en.wikipedia.org/wiki/Abyssinian_(cat)'}
š¶ Dog Data Extraction Overview¶
This function extracts and cleans relevant dog breed information from raw JSON data. It includes:
- Breed details (
id,name,origin,breed_group, etc.) - Structured
temperamentandoriginlists - Cleaned
life_spanstring, ensuring format consistency (e.g.1214ā12-14) - Full
weightandheightdictionaries (if available)
āļø Includes logic to fix malformed life spans with missing hyphens.
import re
import pandas as pd
def extract_dog_values(dog, user_column_value='dog'):
raw_life_span = dog.get('life_span', '')
# Clean life_span: remove unwanted characters
cleaned = re.sub(r'[^0-9\-]', '', raw_life_span).strip()
# Detect and correct patterns like "81-5" or "91-4" using regex.
match = re.fullmatch(r'(\d{2})-(\d)$', cleaned)
if match:
first, second = match.groups()
# Correcting the pattern where the life span seems broken into "XX-X" format
cleaned = f"{first}-{second}"
elif '-' not in cleaned:
# If no hyphen is found, try to insert one based on the length of the string.
if len(cleaned) == 4:
cleaned = cleaned[:2] + '-' + cleaned[2:]
elif len(cleaned) == 3:
cleaned = cleaned[:2] + '-' + cleaned[2:]
elif 0 < len(cleaned) <= 2:
cleaned = f"{cleaned}-{cleaned}"
filtered_life_span = cleaned
raw_origin = dog.get('origin', None)
if isinstance(raw_origin, str):
origin_list = [o.strip() for o in raw_origin.split(',')]
elif isinstance(raw_origin, list):
origin_list = raw_origin
else:
origin_list = []
raw_temperament = dog.get('temperament', '')
if isinstance(raw_temperament, str):
temperament_list = [t.strip() for t in raw_temperament.split(',')]
else:
temperament_list = []
values = {
'id': dog.get('id'),
'type_of_pet': user_column_value,
'breed': dog.get('name', ''),
'origin': origin_list,
'country_code': dog.get('country_code', ''),
'life_span': filtered_life_span,
'temperament': temperament_list,
'weight': dog.get('weight', ''),
'height': dog.get('height', ''),
'bred_for': dog.get('bred_for', ''),
'breed_group': dog.get('breed_group', '')
}
return values
def extract_cat_values(cat, user_column_value='cat'):
"""
Extracts cat breed information into a dictionary and includes a user-supplied column if provided.
:param cat: A dictionary containing cat data.
:param user_column_value: Optional user-supplied data for the new_column field.
:return: A dictionary representing a cat document.
"""
# Process origin
raw_origin = cat.get('origin', '')
if isinstance(raw_origin, str):
origin_list = [o.strip() for o in raw_origin.split(',')] if raw_origin else []
elif isinstance(raw_origin, list):
origin_list = raw_origin
else:
origin_list = []
# Process country_code
raw_country_code = cat.get('country_code', '')
if isinstance(raw_country_code, str):
country_code_list = [c.strip() for c in raw_country_code.split(',')] if raw_country_code else []
elif isinstance(raw_country_code, list):
country_code_list = raw_country_code
else:
country_code_list = []
# Process temperament
raw_temperament = cat.get('temperament', '')
if isinstance(raw_temperament, str):
temperament_list = [t.strip() for t in raw_temperament.split(',')] if raw_temperament else []
elif isinstance(raw_temperament, list):
temperament_list = raw_temperament
else:
temperament_list = []
values = {
'id': cat.get('id', ''),
'type_of_pet': user_column_value,
'breed': cat.get('name', ''),
'origin': origin_list,
'country_code': country_code_list,
'life_span': cat.get('life_span', ''),
'temperament': temperament_list,
'weight': cat.get('weight', ''), # Changed here: no longer accessing ['metric']
'description': cat.get('description', ''),
'affection_level': cat.get('affection_level', ''),
'energy_level': cat.get('energy_level', ''),
'dog_friendly': cat.get('dog_friendly', ''),
'child_friendly': cat.get('child_friendly', ''),
'intelligence': cat.get('intelligence', ''),
'hairless': cat.get('hairless', ''),
'health_issues': cat.get('health_issues', ''),
'hypoallergenic': cat.get('hypoallergenic', ''),
'experimental': cat.get('experimental', ''),
'indoor': cat.get('indoor', ''),
'natural': cat.get('natural', ''),
'rare': cat.get('rare', ''),
'shedding_level': cat.get('shedding_level', ''),
'social_needs': cat.get('social_needs', ''),
'stranger_friendly': cat.get('stranger_friendly', '')
}
# Print the key-value pairs in vertical format for debugging/display
for key, value in values.items():
print(f"{key}: {value}")
return values
# generate list of characters including digits
list_characters = [char for char in string.ascii_lowercase + string.digits]
print(list_characters)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# Initialize an empty list and a set to track unique dog IDs
list_dogs = []
seen_dog_ids = set()
# Download/search dogs by starting char
for i, char in enumerate(list_characters):
print(f'- {char} ({i+1}/{len(list_characters)})', end='\r')
url = f'{API_URL_1}?f={char}'
r = requests.get(url)
data = r.json()
if data: # If there's data, proceed to extract values
for dog in data:
dog_id = dog.get('id')
if dog_id not in seen_dog_ids:
values = extract_dog_values(dog)
list_dogs.append(values)
seen_dog_ids.add(dog_id) # Add dog ID to the set to track it
time.sleep(1) # Throttle requests to avoid being rate-limited
- 9 (36/36)
# Initialize an empty list and a set to track unique cats IDs
list_cats = []
seen_cats_ids = set()
# Download/search cats by starting char
for i, char in enumerate(list_characters):
print(f'- {char} ({i+1}/{len(list_characters)})', end='\r')
url = f'{API_URL_2}?f={char}'
r = requests.get(url)
data = r.json()
if data: # If there's data, proceed to extract values
for cat in data:
cat_id = cat.get('id')
if cat_id not in seen_cats_ids:
values = extract_cat_values(cat)
list_cats.append(values)
seen_cats_ids.add(cat_id) # Add cat ID to the set to track it
time.sleep(1) # Throttle requests to avoid being rate-limited
š¦ NoSQL Schema Description ā Pets DB¶
This NoSQL schema is designed to organize and store structured pet data ā specifically for cats and dogs ā using a document-based model ideal for MongoDB.
šļø Structure Overview¶
petscollection
Serves as the central entry point. Each document includes a unique_idand atype_of_petfield (e.g.,"cat"or"dog").catscollection
Linked by_id, each document includes:breedaffection_level,intelligence,friendliness- Physical traits like
hairless,hypoallergenic,weight
dogscollection
Also linked by_id, each document includes:breedbred_for(purpose of breed origin)weight,height,temperament, andbreed_group
š Why This Design?¶
- Keeps pet types cleanly separated while still linked
- Supports flexible, schema-less attributes per animal type
- Ideal for querying pets by type or specific traits
- Great for learning NoSQL modeling and working with real-world API data
Collections creations¶
# insert the list of dogs (=documents) into MongoDB collection "dogs"
dogs.insert_many(list_dogs);
# count number of documents inserted
dogs.count_documents({})
172
# insert the list of cats (=documents) into MongoDB collection "cats"
cats.insert_many(list_cats);
# count number of documents inserted into cats
print(cats.count_documents({}))
67
# insert the list of cats & dogs (=documents) into MongoDB collection "pets"
pets.insert_many(list_dogs);
pets.insert_many(list_cats);
# count number of documents inserted into pets
print(pets.count_documents({}))
239
# Dictionary to store database and collection info
all_collections = []
# Iterate over all databases
for db_name in client.list_database_names():
db = client[db_name]
for coll_name in db.list_collection_names():
all_collections.append({"database": db_name, "collection": coll_name})
# Convert to DataFrame
colls_df = pd.DataFrame(all_collections)
print(colls_df)
database collection 0 admin system.version 1 catsdb type_cats 2 config system.sessions 3 dogsdb type_dogs 4 local startup_log 5 petsdb type_pets
colls = pd.DataFrame(client['catsdb'].list_collection_names(), columns=["collection"])
colls
| collection | |
|---|---|
| 0 | type_cats |
colls = pd.DataFrame(client['dogsdb'].list_collection_names(), columns=["collection"])
colls
| collection | |
|---|---|
| 0 | type_dogs |
colls = pd.DataFrame(client['petsdb'].list_collection_names(), columns=["collection"])
colls
| collection | |
|---|---|
| 0 | type_pets |
# get one dog from MongoDB
(dogs.find_one())
{'_id': ObjectId('67ed6529b16d68169fd97047'),
'id': 1,
'type_of_pet': 'dog',
'breed': 'Affenpinscher',
'origin': ['Germany', 'France'],
'country_code': '',
'life_span': '10-12',
'temperament': ['Stubborn',
'Curious',
'Playful',
'Adventurous',
'Active',
'Fun-loving'],
'weight': {'imperial': '6 - 13', 'metric': '3 - 6'},
'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
'bred_for': 'Small rodent hunting, lapdog',
'breed_group': 'Toy'}
# get 5 dogs from MongoDB and display as datframe
r = dogs.aggregate([
{"$limit": 5},
])
pd.DataFrame(r)
| _id | id | type_of_pet | breed | origin | country_code | life_span | temperament | weight | height | bred_for | breed_group | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 67ed6529b16d68169fd97047 | 1 | dog | Affenpinscher | [Germany, France] | 10-12 | [Stubborn, Curious, Playful, Adventurous, Acti... | {'imperial': '6 - 13', 'metric': '3 - 6'} | {'imperial': '9 - 11.5', 'metric': '23 - 29'} | Small rodent hunting, lapdog | Toy | |
| 1 | 67ed6529b16d68169fd97048 | 2 | dog | Afghan Hound | [Afghanistan, Iran, Pakistan] | AG | 10-13 | [Aloof, Clownish, Dignified, Independent, Happy] | {'imperial': '50 - 60', 'metric': '23 - 27'} | {'imperial': '25 - 27', 'metric': '64 - 69'} | Coursing and hunting | Hound |
| 2 | 67ed6529b16d68169fd97049 | 3 | dog | African Hunting Dog | [] | 11-11 | [Wild, Hardworking, Dutiful] | {'imperial': '44 - 66', 'metric': '20 - 30'} | {'imperial': '30', 'metric': '76'} | A wild pack animal | ||
| 3 | 67ed6529b16d68169fd9704a | 4 | dog | Airedale Terrier | [United Kingdom, England] | 10-13 | [Outgoing, Friendly, Alert, Confident, Intelli... | {'imperial': '40 - 65', 'metric': '18 - 29'} | {'imperial': '21 - 23', 'metric': '53 - 58'} | Badger, otter hunting | Terrier | |
| 4 | 67ed6529b16d68169fd9704b | 5 | dog | Akbash Dog | [] | 10-12 | [Loyal, Independent, Intelligent, Brave] | {'imperial': '90 - 120', 'metric': '41 - 54'} | {'imperial': '28 - 34', 'metric': '71 - 86'} | Sheep guarding | Working |
ā
Fixing Inconsistencies in life_span Values¶
Inconsistencies were found in the life_span field of the pets_collection. The values 81-5 and 91-4 were incorrectly formatted. These were corrected as follows:
81-5was updated to8-1591-4was updated to9-14
The issue was resolved using the update_many function in MongoDB to ensure a consistent format for the lifespan values_
db = client["dogsdb"]
pets_collection = db["type_dogs"]
# Update the "life_span" field in the collection to fix the ranges
pets_collection.update_many(
{"life_span": "81-5"}, # Condition to find the incorrect value
{"$set": {"life_span": "8-15"}} # Update to the corrected value
)
pets_collection.update_many(
{"life_span": "91-4"}, # Condition to find the incorrect value
{"$set": {"life_span": "9-14"}} # Update to the corrected value
)
# Verify the update by printing the distinct "life_span" values
updated_life_spans = pets_collection.distinct("life_span")
print(updated_life_spans)
['10-10', '10-11', '10-12', '10-13', '10-14', '10-15', '10-16', '10-18', '11-11', '11-13', '11-14', '11-15', '12-12', '12-13', '12-14', '12-15', '12-16', '12-18', '13-14', '13-15', '13-16', '13-17', '14-15', '14-16', '14-18', '15-15', '15-18', '15-20', '18-18', '6-8', '7-10', '8-10', '8-12', '8-15', '9-11', '9-14']
# check collection structure
r = cats.aggregate([
{"$project": {"_id": 0}},
{"$limit": 5},
])
pd.DataFrame(r)
| id | type_of_pet | breed | origin | country_code | life_span | temperament | weight | description | affection_level | ... | hairless | health_issues | hypoallergenic | experimental | indoor | natural | rare | shedding_level | social_needs | stranger_friendly | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | abys | cat | Abyssinian | [Egypt] | [EG] | 14 - 15 | [Active, Energetic, Independent, Intelligent, ... | {'imperial': '7 - 10', 'metric': '3 - 5'} | The Abyssinian is easy to care for, and a joy ... | 5 | ... | 0 | 2 | 0 | 0 | 0 | 1 | 0 | 2 | 5 | 5 |
| 1 | aege | cat | Aegean | [Greece] | [GR] | 9 - 12 | [Affectionate, Social, Intelligent, Playful, A... | {'imperial': '7 - 10', 'metric': '3 - 5'} | Native to the Greek islands known as the Cycla... | 4 | ... | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 3 | 4 | 4 |
| 2 | abob | cat | American Bobtail | [United States] | [US] | 11 - 15 | [Intelligent, Interactive, Lively, Playful, Se... | {'imperial': '7 - 16', 'metric': '3 - 7'} | American Bobtails are loving and incredibly in... | 5 | ... | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 3 | 3 | 3 |
| 3 | acur | cat | American Curl | [United States] | [US] | 12 - 16 | [Affectionate, Curious, Intelligent, Interacti... | {'imperial': '5 - 10', 'metric': '2 - 5'} | Distinguished by truly unique ears that curl b... | 5 | ... | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 3 | 3 | 3 |
| 4 | asho | cat | American Shorthair | [United States] | [US] | 15 - 17 | [Active, Curious, Easy Going, Playful, Calm] | {'imperial': '8 - 15', 'metric': '4 - 7'} | The American Shorthair is known for its longev... | 5 | ... | 0 | 3 | 0 | 0 | 0 | 1 | 0 | 3 | 4 | 3 |
5 rows Ć 24 columns
# List databases
client.list_database_names()
['admin', 'catsdb', 'config', 'dogsdb', 'local', 'petsdb']
Transform
# selection of specific columns of interest
r = dogs.aggregate([
{"$limit": 10},
{
"$project": {
"_id": 0,
"type_of_pet": 1,
"breed": 1,
"country_code": 1,
"origin": 1,
"life_span": 1,
"weight": 1,
"temperament":2,
}
}
])
filtered_pet = pd.DataFrame(r)
filtered_pet
| type_of_pet | breed | origin | country_code | life_span | temperament | weight | |
|---|---|---|---|---|---|---|---|
| 0 | dog | Affenpinscher | [Germany, France] | 10-12 | [Stubborn, Curious, Playful, Adventurous, Acti... | {'imperial': '6 - 13', 'metric': '3 - 6'} | |
| 1 | dog | Afghan Hound | [Afghanistan, Iran, Pakistan] | AG | 10-13 | [Aloof, Clownish, Dignified, Independent, Happy] | {'imperial': '50 - 60', 'metric': '23 - 27'} |
| 2 | dog | African Hunting Dog | [] | 11-11 | [Wild, Hardworking, Dutiful] | {'imperial': '44 - 66', 'metric': '20 - 30'} | |
| 3 | dog | Airedale Terrier | [United Kingdom, England] | 10-13 | [Outgoing, Friendly, Alert, Confident, Intelli... | {'imperial': '40 - 65', 'metric': '18 - 29'} | |
| 4 | dog | Akbash Dog | [] | 10-12 | [Loyal, Independent, Intelligent, Brave] | {'imperial': '90 - 120', 'metric': '41 - 54'} | |
| 5 | dog | Akita | [] | 10-14 | [Docile, Alert, Responsive, Dignified, Compose... | {'imperial': '65 - 115', 'metric': '29 - 52'} | |
| 6 | dog | Alapaha Blue Blood Bulldog | [] | 12-13 | [Loving, Protective, Trainable, Dutiful, Respo... | {'imperial': '55 - 90', 'metric': '25 - 41'} | |
| 7 | dog | Alaskan Husky | [] | 10-13 | [Friendly, Energetic, Loyal, Gentle, Confident] | {'imperial': '38 - 50', 'metric': '17 - 23'} | |
| 8 | dog | Alaskan Malamute | [] | 12-15 | [Friendly, Affectionate, Devoted, Loyal, Digni... | {'imperial': '65 - 100', 'metric': '29 - 45'} | |
| 9 | dog | American Bulldog | [] | 10-12 | [Friendly, Assertive, Energetic, Loyal, Gentle... | {'imperial': '60 - 120', 'metric': '27 - 54'} |
š Transformation¶
š Adding Geo Coordinates to type_dogs & type_cats¶
Geo location data is added to both collections using the $set operator with updateMany.
š ļø Action:¶
- A new field
geocord(geo coordinates) is added to all documents in:type_dogstype_cats
This allows for future geospatial queries and visualizations, improving data usability for mapping or location-based features.
db = client["dogsdb"]
pets_collection = db["type_dogs"]
# Add a new field "geocord" to every document
result = pets_collection.update_many(
{},
{"$set": {"geocord":""}}
)
print(f"Modified {result.modified_count} documents.")
Modified 172 documents.
Adding fields via Update many via set
db = client["catsdb"]
pets_collection = db["type_cats"] # or whichever collection name you use
# Add a new field "geocord" to every document
result = pets_collection.update_many(
{},
{"$set": {"geocord":""}}
)
print(f"Modified {result.modified_count} documents.")
Modified 67 documents.
We check the new column
db = client["dogsdb"]
pets_collection = db["type_dogs"]
# Fetch a document to check (for example, the first one)
doc = pets_collection.find_one({})
pp.pprint(doc)
{'_id': ObjectId('67ed6529b16d68169fd97047'),
'bred_for': 'Small rodent hunting, lapdog',
'breed': 'Affenpinscher',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
'id': 1,
'life_span': '10-12',
'origin': ['Germany', 'France'],
'temperament': ['Stubborn',
'Curious',
'Playful',
'Adventurous',
'Active',
'Fun-loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
db = client["catsdb"]
pets_collection = db["type_cats"]
# Fetch a document to check (for example, the first one)
doc = pets_collection.find_one({})
pp.pprint(doc)
{'_id': ObjectId('67ed652ab16d68169fd970f3'),
'affection_level': 5,
'breed': 'Abyssinian',
'child_friendly': 3,
'country_code': ['EG'],
'description': 'The Abyssinian is easy to care for, and a joy to have in your '
'home. Theyāre affectionate cats and love both people and '
'other animals.',
'dog_friendly': 4,
'energy_level': 5,
'experimental': 0,
'geocord': '',
'hairless': 0,
'health_issues': 2,
'hypoallergenic': 0,
'id': 'abys',
'indoor': 0,
'intelligence': 5,
'life_span': '14 - 15',
'natural': 1,
'origin': ['Egypt'],
'rare': 0,
'shedding_level': 2,
'social_needs': 5,
'stranger_friendly': 5,
'temperament': ['Active', 'Energetic', 'Independent', 'Intelligent', 'Gentle'],
'type_of_pet': 'cat',
'weight': {'imperial': '7 - 10', 'metric': '3 - 5'}}
š Source of Extracting Geo Coordinates¶
Geo coordinates are derived based on each petās country of origin.
šŗļø How It's Done:¶
- The
originfield (e.g.,"Germany","France") is used as a reference. - A separate dataset or API (such as openstreetmap) provides latitude and longitude for each country.
- These coordinates are mapped and inserted into the
geocordfield in bothtype_dogsandtype_cats.
This enriches the dataset for future use in geospatial analysis or map visualizations.
url = "https://nominatim.openstreetmap.org/search"
params = {
'country': 'Germany',
'format': 'json'
}
headers = {
'User-Agent': 'MyAwesomeApp/1.0 (myemail@example.com)'
}
response = requests.get(url, params=params, headers=headers)
data = response.json()
pp.pprint(data)
[{'addresstype': 'country',
'boundingbox': ['47.2701114', '55.0991610', '5.8663153', '15.0419309'],
'class': 'boundary',
'display_name': 'Deutschland',
'importance': 0.9450694379594134,
'lat': '51.1638175',
'licence': 'Data Ā© OpenStreetMap contributors, ODbL 1.0. '
'http://osm.org/copyright',
'lon': '10.4478313',
'name': 'Deutschland',
'osm_id': 51477,
'osm_type': 'relation',
'place_id': 125322550,
'place_rank': 4,
'type': 'administrative'}]
Extracting origin from from type_dogs collection, and adding coordinates to empty column 'geocord'
import time
import requests
db = client["dogsdb"]
collection = db["type_dogs"]
for pet in collection.find():
origin_field = pet.get("origin")
# Skip if origin is missing
if not origin_field:
continue
# Normalize origin to a string: take the first item if it's a list
if isinstance(origin_field, list) and origin_field:
origin_value = origin_field[0]
elif isinstance(origin_field, str):
origin_value = origin_field.split(",")[0].strip()
else:
# Unsupported format
continue
# Skip if the value is "Unknown"
if origin_value.strip().lower() == "N/A":
continue
# Prepare the request to Nominatim
url = "https://nominatim.openstreetmap.org/search"
params = {
"country": origin_value,
"format": "json"
}
headers = {
"User-Agent": "MyAwesomeApp/1.0 (myemail@example.com)"
}
try:
response = requests.get(url, params=params, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
except requests.RequestException as e:
print(f"Request failed for origin '{origin_value}': {e}")
continue
if data:
try:
lat = float(data[0].get("lat", 0))
lon = float(data[0].get("lon", 0))
result = collection.update_one(
{"_id": pet["_id"]},
{"$set": {"geocord": {"lat": lat, "lon": lon}}}
)
if result.matched_count > 0:
print(f"Updated doc _id={pet['_id']} with lat={lat}, lon={lon}")
else:
print(f"No document matched for _id={pet['_id']}")
except (ValueError, KeyError) as e:
print(f"Failed to parse lat/lon for origin '{origin_value}': {e}")
else:
print(f"No results for origin '{origin_value}'")
time.sleep(1)
# Confirm an example update
check_pet = collection.find_one({"_id": pet["_id"]})
print("Example updated pet with geocord:", check_pet.get("geocord"))
Updated doc _id=67ed6529b16d68169fd97047 with lat=51.1638175, lon=10.4478313 Updated doc _id=67ed6529b16d68169fd97048 with lat=33.7680065, lon=66.2385139 Request failed for origin '': 400 Client Error: Bad Request for url: https://nominatim.openstreetmap.org/search?country=&format=json Updated doc _id=67ed6529b16d68169fd9704a with lat=54.7023545, lon=-3.2765753 Request failed for origin '': 400 Client Error: Bad Request for url: https://nominatim.openstreetmap.org/search?country=&format=json Example updated pet with geocord:
We check the results
# Query documents that have a 'geocord' field
updated_docs = collection.find({"geocord": {"$exists": True}})
for doc in updated_docs:
pp.pprint(doc)
{'_id': ObjectId('67ed6529b16d68169fd97047'),
'bred_for': 'Small rodent hunting, lapdog',
'breed': 'Affenpinscher',
'breed_group': 'Toy',
'country_code': '',
'geocord': {'lat': 51.1638175, 'lon': 10.4478313},
'height': {'imperial': '9 - 11.5', 'metric': '23 - 29'},
'id': 1,
'life_span': '10-12',
'origin': ['Germany', 'France'],
'temperament': ['Stubborn',
'Curious',
'Playful',
'Adventurous',
'Active',
'Fun-loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97048'),
'bred_for': 'Coursing and hunting',
'breed': 'Afghan Hound',
'breed_group': 'Hound',
'country_code': 'AG',
'geocord': {'lat': 33.7680065, 'lon': 66.2385139},
'height': {'imperial': '25 - 27', 'metric': '64 - 69'},
'id': 2,
'life_span': '10-13',
'origin': ['Afghanistan', 'Iran', 'Pakistan'],
'temperament': ['Aloof', 'Clownish', 'Dignified', 'Independent', 'Happy'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97049'),
'bred_for': 'A wild pack animal',
'breed': 'African Hunting Dog',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '30', 'metric': '76'},
'id': 3,
'life_span': '11-11',
'origin': [''],
'temperament': ['Wild', 'Hardworking', 'Dutiful'],
'type_of_pet': 'dog',
'weight': {'imperial': '44 - 66', 'metric': '20 - 30'}}
{'_id': ObjectId('67ed6529b16d68169fd9704a'),
'bred_for': 'Badger, otter hunting',
'breed': 'Airedale Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': {'lat': 54.7023545, 'lon': -3.2765753},
'height': {'imperial': '21 - 23', 'metric': '53 - 58'},
'id': 4,
'life_span': '10-13',
'origin': ['United Kingdom', 'England'],
'temperament': ['Outgoing',
'Friendly',
'Alert',
'Confident',
'Intelligent',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd9704b'),
'bred_for': 'Sheep guarding',
'breed': 'Akbash Dog',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '28 - 34', 'metric': '71 - 86'},
'id': 5,
'life_span': '10-12',
'origin': [''],
'temperament': ['Loyal', 'Independent', 'Intelligent', 'Brave'],
'type_of_pet': 'dog',
'weight': {'imperial': '90 - 120', 'metric': '41 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9704c'),
'bred_for': 'Hunting bears',
'breed': 'Akita',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 28', 'metric': '61 - 71'},
'id': 6,
'life_span': '10-14',
'origin': [],
'temperament': ['Docile',
'Alert',
'Responsive',
'Dignified',
'Composed',
'Friendly',
'Receptive',
'Faithful',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 115', 'metric': '29 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd9704d'),
'bred_for': 'Guarding',
'breed': 'Alapaha Blue Blood Bulldog',
'breed_group': 'Mixed',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 24', 'metric': '46 - 61'},
'id': 7,
'life_span': '12-13',
'origin': [],
'temperament': ['Loving', 'Protective', 'Trainable', 'Dutiful', 'Responsible'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 90', 'metric': '25 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9704e'),
'bred_for': 'Sled pulling',
'breed': 'Alaskan Husky',
'breed_group': 'Mixed',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 26', 'metric': '58 - 66'},
'id': 8,
'life_span': '10-13',
'origin': [],
'temperament': ['Friendly', 'Energetic', 'Loyal', 'Gentle', 'Confident'],
'type_of_pet': 'dog',
'weight': {'imperial': '38 - 50', 'metric': '17 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd9704f'),
'bred_for': 'Hauling heavy freight, Sled pulling',
'breed': 'Alaskan Malamute',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 25', 'metric': '58 - 64'},
'id': 9,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly',
'Affectionate',
'Devoted',
'Loyal',
'Dignified',
'Playful'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 100', 'metric': '29 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd97050'),
'bred_for': '',
'breed': 'American Bulldog',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
'id': 10,
'life_span': '10-12',
'origin': [],
'temperament': ['Friendly',
'Assertive',
'Energetic',
'Loyal',
'Gentle',
'Confident',
'Dominant'],
'type_of_pet': 'dog',
'weight': {'imperial': '60 - 120', 'metric': '27 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd97051'),
'bred_for': 'Family companion dog',
'breed': 'American Bully',
'breed_group': '',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '14 - 17', 'metric': '36 - 43'},
'id': 11,
'life_span': '8-15',
'origin': [],
'temperament': ['Strong Willed',
'Stubborn',
'Friendly',
'Clownish',
'Affectionate',
'Loyal',
'Obedient',
'Intelligent',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 150', 'metric': '14 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd97052'),
'bred_for': 'Circus performer',
'breed': 'American Eskimo Dog',
'breed_group': 'Non-Sporting',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '15 - 19', 'metric': '38 - 48'},
'id': 12,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly', 'Alert', 'Reserved', 'Intelligent', 'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 40', 'metric': '9 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97053'),
'bred_for': 'Companionship',
'breed': 'American Eskimo Dog (Miniature)',
'breed_group': '',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '9 - 12', 'metric': '23 - 30'},
'id': 13,
'life_span': '13-15',
'origin': [],
'temperament': ['Friendly', 'Alert', 'Reserved', 'Intelligent', 'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '7 - 10', 'metric': '3 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd97054'),
'bred_for': 'Fox hunting, scent hound',
'breed': 'American Foxhound',
'breed_group': 'Hound',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '21 - 28', 'metric': '53 - 71'},
'id': 14,
'life_span': '8-15',
'origin': [],
'temperament': ['Kind',
'Sweet-Tempered',
'Loyal',
'Independent',
'Intelligent',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 75', 'metric': '29 - 34'}}
{'_id': ObjectId('67ed6529b16d68169fd97055'),
'bred_for': 'Fighting',
'breed': 'American Pit Bull Terrier',
'breed_group': 'Terrier',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '17 - 21', 'metric': '43 - 53'},
'id': 15,
'life_span': '10-15',
'origin': [],
'temperament': ['Strong Willed',
'Stubborn',
'Friendly',
'Clownish',
'Affectionate',
'Loyal',
'Obedient',
'Intelligent',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 60', 'metric': '14 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97056'),
'bred_for': '',
'breed': 'American Staffordshire Terrier',
'breed_group': 'Terrier',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '17 - 19', 'metric': '43 - 48'},
'id': 16,
'life_span': '12-15',
'origin': [],
'temperament': ['Tenacious',
'Friendly',
'Devoted',
'Loyal',
'Attentive',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97057'),
'bred_for': 'Bird flushing and retrieving',
'breed': 'American Water Spaniel',
'breed_group': 'Sporting',
'country_code': 'US',
'geocord': '',
'height': {'imperial': '15 - 18', 'metric': '38 - 46'},
'id': 17,
'life_span': '10-12',
'origin': [],
'temperament': ['Friendly',
'Energetic',
'Obedient',
'Intelligent',
'Protective',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 45', 'metric': '11 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97058'),
'bred_for': 'Livestock herding',
'breed': 'Anatolian Shepherd Dog',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '27 - 29', 'metric': '69 - 74'},
'id': 18,
'life_span': '11-13',
'origin': [],
'temperament': ['Steady',
'Bold',
'Independent',
'Confident',
'Intelligent',
'Proud'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 150', 'metric': '36 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd97059'),
'bred_for': 'Herding livestock, pulling carts, and guarding the farm',
'breed': 'Appenzeller Sennenhund',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 22', 'metric': '51 - 56'},
'id': 19,
'life_span': '12-14',
'origin': [],
'temperament': ['Reliable', 'Fearless', 'Energetic', 'Lively', 'Self-assured'],
'type_of_pet': 'dog',
'weight': {'imperial': '48 - 55', 'metric': '22 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9705a'),
'bred_for': 'Cattle herding, herding trials',
'breed': 'Australian Cattle Dog',
'breed_group': 'Herding',
'country_code': 'AU',
'geocord': '',
'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
'id': 21,
'life_span': '12-14',
'origin': [],
'temperament': ['Cautious',
'Energetic',
'Loyal',
'Obedient',
'Protective',
'Brave'],
'type_of_pet': 'dog',
'weight': {'imperial': '44 - 62', 'metric': '20 - 28'}}
{'_id': ObjectId('67ed6529b16d68169fd9705b'),
'bred_for': 'Farm dog, Cattle herding',
'breed': 'Australian Kelpie',
'breed_group': 'Herding',
'country_code': 'AU',
'geocord': '',
'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
'id': 22,
'life_span': '10-13',
'origin': [],
'temperament': ['Friendly',
'Energetic',
'Alert',
'Loyal',
'Intelligent',
'Eager'],
'type_of_pet': 'dog',
'weight': {'imperial': '31 - 46', 'metric': '14 - 21'}}
{'_id': ObjectId('67ed6529b16d68169fd9705c'),
'bred_for': 'Sheep herding',
'breed': 'Australian Shepherd',
'breed_group': 'Herding',
'country_code': 'AU',
'geocord': '',
'height': {'imperial': '18 - 23', 'metric': '46 - 58'},
'id': 23,
'life_span': '12-16',
'origin': [],
'temperament': ['Good-natured',
'Affectionate',
'Intelligent',
'Active',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 65', 'metric': '16 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd9705d'),
'bred_for': 'Cattle herdering, hunting snakes and rodents',
'breed': 'Australian Terrier',
'breed_group': 'Terrier',
'country_code': 'AU',
'geocord': '',
'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
'id': 24,
'life_span': '15-15',
'origin': [],
'temperament': ['Spirited',
'Alert',
'Loyal',
'Companionable',
'Even Tempered',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '14 - 16', 'metric': '6 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd9705e'),
'bred_for': 'Livestock guardian, hunting',
'breed': 'Azawakh',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 29', 'metric': '58 - 74'},
'id': 25,
'life_span': '10-13',
'origin': [],
'temperament': ['Aloof',
'Affectionate',
'Attentive',
'Rugged',
'Fierce',
'Refined'],
'type_of_pet': 'dog',
'weight': {'imperial': '33 - 55', 'metric': '15 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9705f'),
'bred_for': 'Hunting water game',
'breed': 'Barbet',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 26', 'metric': '51 - 66'},
'id': 26,
'life_span': '13-15',
'origin': [],
'temperament': ['Obedient', 'Companionable', 'Intelligent', 'Joyful'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97060'),
'bred_for': 'Hunting',
'breed': 'Basenji',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
'id': 28,
'life_span': '10-12',
'origin': [],
'temperament': ['Affectionate',
'Energetic',
'Alert',
'Curious',
'Playful',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '22 - 24', 'metric': '10 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd97061'),
'bred_for': 'Hunting on foot.',
'breed': 'Basset Bleu de Gascogne',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
'id': 29,
'life_span': '10-14',
'origin': [],
'temperament': ['Affectionate',
'Lively',
'Agile',
'Curious',
'Happy',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 40', 'metric': '16 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97062'),
'bred_for': 'Hunting by scent',
'breed': 'Basset Hound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '14', 'metric': '36'},
'id': 30,
'life_span': '12-15',
'origin': [],
'temperament': ['Tenacious',
'Friendly',
'Affectionate',
'Devoted',
'Sweet-Tempered',
'Gentle'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 65', 'metric': '23 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97063'),
'bred_for': 'Rabbit, hare hunting',
'breed': 'Beagle',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
'id': 31,
'life_span': '13-16',
'origin': [],
'temperament': ['Amiable',
'Even Tempered',
'Excitable',
'Determined',
'Gentle',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 35', 'metric': '9 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd97064'),
'bred_for': 'Sheep herding',
'breed': 'Bearded Collie',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 22', 'metric': '51 - 56'},
'id': 32,
'life_span': '12-14',
'origin': [],
'temperament': ['Self-confidence',
'Hardy',
'Lively',
'Alert',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 55', 'metric': '20 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd97065'),
'bred_for': 'Boar herding, hunting, guarding',
'breed': 'Beauceron',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 27.5', 'metric': '61 - 70'},
'id': 33,
'life_span': '10-12',
'origin': [],
'temperament': ['Fearless', 'Friendly', 'Intelligent', 'Protective', 'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 110', 'metric': '36 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd97066'),
'bred_for': 'Killing rat, badger, other vermin',
'breed': 'Bedlington Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '15 - 16', 'metric': '38 - 41'},
'id': 34,
'life_span': '14-16',
'origin': [],
'temperament': ['Affectionate', 'Spirited', 'Intelligent', 'Good-tempered'],
'type_of_pet': 'dog',
'weight': {'imperial': '17 - 23', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd97067'),
'bred_for': 'Stock herding',
'breed': 'Belgian Malinois',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
'id': 36,
'life_span': '12-14',
'origin': [],
'temperament': ['Watchful',
'Alert',
'Stubborn',
'Friendly',
'Confident',
'Hard-working',
'Active',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 80', 'metric': '18 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd97068'),
'bred_for': 'Guarding, Drafting, Police work.',
'breed': 'Belgian Tervuren',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
'id': 38,
'life_span': '10-12',
'origin': [],
'temperament': ['Energetic',
'Alert',
'Loyal',
'Intelligent',
'Attentive',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 65', 'metric': '18 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd97069'),
'bred_for': 'Draft work',
'breed': 'Bernese Mountain Dog',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 27.5', 'metric': '58 - 70'},
'id': 41,
'life_span': '7-10',
'origin': [],
'temperament': ['Affectionate', 'Loyal', 'Intelligent', 'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 120', 'metric': '29 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9706a'),
'bred_for': 'Companion',
'breed': 'Bichon Frise',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '9.5 - 11.5', 'metric': '24 - 29'},
'id': 42,
'life_span': '15-15',
'origin': [],
'temperament': ['Feisty',
'Affectionate',
'Cheerful',
'Playful',
'Gentle',
'Sensitive'],
'type_of_pet': 'dog',
'weight': {'imperial': '10 - 18', 'metric': '5 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd9706b'),
'bred_for': 'Hunting raccoons, night hunting',
'breed': 'Black and Tan Coonhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
'id': 43,
'life_span': '10-12',
'origin': [],
'temperament': ['Easygoing',
'Gentle',
'Adaptable',
'Trusting',
'Even Tempered',
'Lovable'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 100', 'metric': '29 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd9706c'),
'bred_for': 'Trailing',
'breed': 'Bloodhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
'id': 45,
'life_span': '8-10',
'origin': [],
'temperament': ['Stubborn', 'Affectionate', 'Gentle', 'Even Tempered'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 110', 'metric': '36 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd9706d'),
'bred_for': 'Hunting with a superior sense of smell.',
'breed': 'Bluetick Coonhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 27', 'metric': '53 - 69'},
'id': 47,
'life_span': '12-14',
'origin': [],
'temperament': ['Friendly', 'Intelligent', 'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9706e'),
'bred_for': 'Guarding the homestead, farm work.',
'breed': 'Boerboel',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
'id': 48,
'life_span': '10-12',
'origin': [],
'temperament': ['Obedient',
'Confident',
'Intelligent',
'Dominant',
'Territorial'],
'type_of_pet': 'dog',
'weight': {'imperial': '110 - 200', 'metric': '50 - 91'}}
{'_id': ObjectId('67ed6529b16d68169fd9706f'),
'bred_for': 'Sheep herder',
'breed': 'Border Collie',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
'id': 50,
'life_span': '12-16',
'origin': [],
'temperament': ['Tenacious',
'Keen',
'Energetic',
'Responsive',
'Alert',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 45', 'metric': '14 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97070'),
'bred_for': 'Fox bolting, ratting',
'breed': 'Border Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '11 - 16', 'metric': '28 - 41'},
'id': 51,
'life_span': '12-14',
'origin': [],
'temperament': ['Fearless',
'Affectionate',
'Alert',
'Obedient',
'Intelligent',
'Even Tempered'],
'type_of_pet': 'dog',
'weight': {'imperial': '11.5 - 15.5', 'metric': '5 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd97071'),
'bred_for': 'Ratting, Companionship',
'breed': 'Boston Terrier',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
'id': 53,
'life_span': '11-13',
'origin': [],
'temperament': ['Friendly', 'Lively', 'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '10 - 25', 'metric': '5 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd97072'),
'bred_for': 'Cattle herding',
'breed': 'Bouvier des Flandres',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
'id': 54,
'life_span': '10-15',
'origin': [],
'temperament': ['Protective',
'Loyal',
'Gentle',
'Intelligent',
'Familial',
'Rational'],
'type_of_pet': 'dog',
'weight': {'imperial': '70 - 110', 'metric': '32 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd97073'),
'bred_for': 'Bull-baiting, guardian',
'breed': 'Boxer',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '21.5 - 25', 'metric': '55 - 64'},
'id': 55,
'life_span': '8-10',
'origin': [],
'temperament': ['Devoted',
'Fearless',
'Friendly',
'Cheerful',
'Energetic',
'Loyal',
'Playful',
'Confident',
'Intelligent',
'Bright',
'Brave',
'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97074'),
'bred_for': 'Turkey retrieving',
'breed': 'Boykin Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 18', 'metric': '36 - 46'},
'id': 56,
'life_span': '10-14',
'origin': [],
'temperament': ['Friendly',
'Energetic',
'Companionable',
'Intelligent',
'Eager',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 40', 'metric': '11 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd97075'),
'bred_for': 'Versatile gun dog',
'breed': 'Bracco Italiano',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21.5 - 26.5', 'metric': '55 - 67'},
'id': 57,
'life_span': '10-12',
'origin': [],
'temperament': ['Stubborn',
'Affectionate',
'Loyal',
'Playful',
'Companionable',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 88', 'metric': '25 - 40'}}
{'_id': ObjectId('67ed6529b16d68169fd97076'),
'bred_for': 'Herding, guarding sheep',
'breed': 'Briard',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
'id': 58,
'life_span': '10-12',
'origin': [],
'temperament': ['Fearless',
'Loyal',
'Obedient',
'Intelligent',
'Faithful',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '70 - 90', 'metric': '32 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd97077'),
'bred_for': 'Pointing, retrieving',
'breed': 'Brittany',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17.5 - 20.5', 'metric': '44 - 52'},
'id': 59,
'life_span': '12-14',
'origin': [],
'temperament': ['Agile',
'Adaptable',
'Quick',
'Intelligent',
'Attentive',
'Happy'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 45', 'metric': '14 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97078'),
'bred_for': 'Bull baiting, Fighting',
'breed': 'Bull Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 22', 'metric': '53 - 56'},
'id': 61,
'life_span': '10-12',
'origin': [],
'temperament': ['Trainable', 'Protective', 'Sweet-Tempered', 'Keen', 'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97079'),
'bred_for': "An elegant man's fashion statement",
'breed': 'Bull Terrier (Miniature)',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 14', 'metric': '25 - 36'},
'id': 62,
'life_span': '11-14',
'origin': [],
'temperament': ['Trainable',
'Protective',
'Sweet-Tempered',
'Keen',
'Active',
'Territorial'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 33', 'metric': '11 - 15'}}
{'_id': ObjectId('67ed6529b16d68169fd9707a'),
'bred_for': 'Estate guardian',
'breed': 'Bullmastiff',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
'id': 64,
'life_span': '8-12',
'origin': [],
'temperament': ['Docile',
'Reliable',
'Devoted',
'Alert',
'Loyal',
'Reserved',
'Loving',
'Protective',
'Powerful',
'Calm',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '100 - 130', 'metric': '45 - 59'}}
{'_id': ObjectId('67ed6529b16d68169fd9707b'),
'bred_for': 'Bolting of otter, foxes, other vermin',
'breed': 'Cairn Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
'id': 65,
'life_span': '14-15',
'origin': [],
'temperament': ['Hardy',
'Fearless',
'Assertive',
'Gay',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '13 - 14', 'metric': '6 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd9707c'),
'bred_for': 'Companion, guard dog, and hunter',
'breed': 'Cane Corso',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
'id': 67,
'life_span': '10-11',
'origin': [],
'temperament': ['Trainable',
'Reserved',
'Stable',
'Quiet',
'Even Tempered',
'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '88 - 120', 'metric': '40 - 54'}}
{'_id': ObjectId('67ed6529b16d68169fd9707d'),
'bred_for': 'Cattle droving',
'breed': 'Cardigan Welsh Corgi',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '10.5 - 12.5', 'metric': '27 - 32'},
'id': 68,
'life_span': '12-14',
'origin': [],
'temperament': ['Affectionate',
'Devoted',
'Alert',
'Companionable',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 38', 'metric': '11 - 17'}}
{'_id': ObjectId('67ed6529b16d68169fd9707e'),
'bred_for': 'Driving livestock',
'breed': 'Catahoula Leopard Dog',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 26', 'metric': '51 - 66'},
'id': 69,
'life_span': '10-12',
'origin': [],
'temperament': ['Energetic',
'Inquisitive',
'Independent',
'Gentle',
'Intelligent',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 95', 'metric': '23 - 43'}}
{'_id': ObjectId('67ed6529b16d68169fd9707f'),
'bred_for': 'Guard dogs, defending sheep from predators, mainly wolves, '
'jackals and bears',
'breed': 'Caucasian Shepherd (Ovcharka)',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 33.5', 'metric': '61 - 85'},
'id': 70,
'life_span': '10-12',
'origin': [],
'temperament': ['Alert', 'Quick', 'Dominant', 'Powerful', 'Calm', 'Strong'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd97080'),
'bred_for': 'Flushing small birds, companion',
'breed': 'Cavalier King Charles Spaniel',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '12 - 13', 'metric': '30 - 33'},
'id': 71,
'life_span': '10-14',
'origin': [],
'temperament': ['Fearless',
'Affectionate',
'Sociable',
'Patient',
'Playful',
'Adaptable'],
'type_of_pet': 'dog',
'weight': {'imperial': '13 - 18', 'metric': '6 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd97081'),
'bred_for': 'Water Retriever',
'breed': 'Chesapeake Bay Retriever',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 26', 'metric': '53 - 66'},
'id': 76,
'life_span': '10-13',
'origin': [],
'temperament': ['Affectionate',
'Intelligent',
'Quiet',
'Dominant',
'Happy',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 80', 'metric': '25 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd97082'),
'bred_for': 'Ratting, lapdog, curio',
'breed': 'Chinese Crested',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '11 - 13', 'metric': '28 - 33'},
'id': 78,
'life_span': '10-14',
'origin': [],
'temperament': ['Affectionate',
'Sweet-Tempered',
'Lively',
'Alert',
'Playful',
'Happy'],
'type_of_pet': 'dog',
'weight': {'imperial': '10 - 13', 'metric': '5 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97083'),
'bred_for': 'Fighting',
'breed': 'Chinese Shar-Pei',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 20', 'metric': '46 - 51'},
'id': 79,
'life_span': '10-10',
'origin': [],
'temperament': ['Suspicious',
'Affectionate',
'Devoted',
'Reserved',
'Independent',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 60', 'metric': '20 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd97084'),
'bred_for': 'Sled pulling',
'breed': 'Chinook',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
'id': 80,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly', 'Alert', 'Dignified', 'Intelligent', 'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 90', 'metric': '23 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd97085'),
'bred_for': 'Guardian, cart pulling, hunting',
'breed': 'Chow Chow',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
'id': 81,
'life_span': '12-15',
'origin': [],
'temperament': ['Aloof', 'Loyal', 'Independent', 'Quiet'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 70', 'metric': '18 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97086'),
'bred_for': 'Bird flushing, retrieving',
'breed': 'Clumber Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
'id': 84,
'life_span': '10-12',
'origin': [],
'temperament': ['Affectionate',
'Loyal',
'Dignified',
'Gentle',
'Calm',
'Great-hearted'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 85', 'metric': '25 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd97087'),
'bred_for': 'Bird flushing, retrieving',
'breed': 'Cocker Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 15', 'metric': '36 - 38'},
'id': 86,
'life_span': '12-15',
'origin': [],
'temperament': ['Trainable',
'Friendly',
'Affectionate',
'Playful',
'Quiet',
'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd97088'),
'bred_for': 'Hunting the American woodcock',
'breed': 'Cocker Spaniel (American)',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 15', 'metric': '36 - 38'},
'id': 87,
'life_span': '12-15',
'origin': [],
'temperament': ['Outgoing',
'Sociable',
'Trusting',
'Joyful',
'Even Tempered',
'Merry'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd97089'),
'bred_for': 'Accompanying ladies on long sea voyages, ratters onboard ship.',
'breed': 'Coton de Tulear',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
'id': 89,
'life_span': '13-16',
'origin': [],
'temperament': ['Affectionate',
'Lively',
'Playful',
'Intelligent',
'Trainable',
'Vocal'],
'type_of_pet': 'dog',
'weight': {'imperial': '9 - 15', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd9708a'),
'bred_for': 'Carriage dog - trot alongside carriages to protect the occupants '
'from banditry or other interference',
'breed': 'Dalmatian',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '19 - 23', 'metric': '48 - 58'},
'id': 92,
'life_span': '10-13',
'origin': [],
'temperament': ['Outgoing',
'Friendly',
'Energetic',
'Playful',
'Sensitive',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 55', 'metric': '23 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd9708b'),
'bred_for': 'Guardian',
'breed': 'Doberman Pinscher',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 28', 'metric': '61 - 71'},
'id': 94,
'life_span': '10-10',
'origin': [],
'temperament': ['Fearless',
'Energetic',
'Alert',
'Loyal',
'Obedient',
'Confident',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '66 - 88', 'metric': '30 - 40'}}
{'_id': ObjectId('67ed6529b16d68169fd9708c'),
'bred_for': 'Big-game hunting',
'breed': 'Dogo Argentino',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '23.5 - 27', 'metric': '60 - 69'},
'id': 95,
'life_span': '10-12',
'origin': [],
'temperament': ['Friendly',
'Affectionate',
'Cheerful',
'Loyal',
'Tolerant',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd9708d'),
'bred_for': 'Farms, watchdog, guard duty',
'breed': 'Dutch Shepherd',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 24.5', 'metric': '56 - 62'},
'id': 98,
'life_span': '15-15',
'origin': [],
'temperament': ['Reliable',
'Affectionate',
'Alert',
'Loyal',
'Obedient',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd9708e'),
'bred_for': 'Bird setting, retrieving',
'breed': 'English Setter',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 25', 'metric': '61 - 64'},
'id': 101,
'life_span': '12-12',
'origin': [],
'temperament': ['Strong Willed',
'Mischievous',
'Affectionate',
'Energetic',
'Playful',
'Companionable',
'Gentle',
'Hard-working',
'Intelligent',
'Eager',
'People-Oriented'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9708f'),
'bred_for': 'Herding & guarding livestock, farm watch dog',
'breed': 'English Shepherd',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 23', 'metric': '46 - 58'},
'id': 102,
'life_span': '10-13',
'origin': [],
'temperament': ['Kind',
'Energetic',
'Independent',
'Adaptable',
'Intelligent',
'Bossy'],
'type_of_pet': 'dog',
'weight': {'imperial': '44 - 66', 'metric': '20 - 30'}}
{'_id': ObjectId('67ed6529b16d68169fd97090'),
'bred_for': 'Bird flushing, retrieving',
'breed': 'English Springer Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '19 - 20', 'metric': '48 - 51'},
'id': 103,
'life_span': '12-14',
'origin': [],
'temperament': ['Affectionate',
'Cheerful',
'Alert',
'Intelligent',
'Attentive',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd97091'),
'bred_for': 'Companion of kings',
'breed': 'English Toy Spaniel',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '10', 'metric': '25'},
'id': 104,
'life_span': '10-12',
'origin': [],
'temperament': ['Affectionate',
'Reserved',
'Playful',
'Gentle',
'Happy',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '8 - 14', 'metric': '4 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd97092'),
'bred_for': 'Rat-baiting',
'breed': 'English Toy Terrier',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
'id': 105,
'life_span': '12-13',
'origin': [],
'temperament': ['Stubborn',
'Alert',
'Companionable',
'Intelligent',
'Cunning',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '6 - 8', 'metric': '3 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd97093'),
'bred_for': 'Companionship',
'breed': 'Eurasier',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '20.5 - 23.5', 'metric': '52 - 60'},
'id': 107,
'life_span': '12-14',
'origin': [],
'temperament': ['Alert',
'Reserved',
'Intelligent',
'Even Tempered',
'Watchful',
'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 70', 'metric': '18 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd97094'),
'bred_for': 'Bird flushing, retrieving',
'breed': 'Field Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 18', 'metric': '43 - 46'},
'id': 108,
'life_span': '11-15',
'origin': [],
'temperament': ['Docile',
'Cautious',
'Sociable',
'Sensitive',
'Adaptable',
'Familial'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd97095'),
'bred_for': 'Herding reindeer',
'breed': 'Finnish Lapphund',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 21', 'metric': '41 - 53'},
'id': 110,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly', 'Keen', 'Faithful', 'Calm', 'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '33 - 53', 'metric': '15 - 24'}}
{'_id': ObjectId('67ed6529b16d68169fd97096'),
'bred_for': 'Hunting birds, small mammals',
'breed': 'Finnish Spitz',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '15.5 - 20', 'metric': '39 - 51'},
'id': 111,
'life_span': '12-15',
'origin': [],
'temperament': ['Playful',
'Loyal',
'Independent',
'Intelligent',
'Happy',
'Vocal'],
'type_of_pet': 'dog',
'weight': {'imperial': '23 - 28', 'metric': '10 - 13'}}
{'_id': ObjectId('67ed6529b16d68169fd97097'),
'bred_for': 'Lapdog',
'breed': 'French Bulldog',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '11 - 12', 'metric': '28 - 30'},
'id': 113,
'life_span': '9-11',
'origin': [],
'temperament': ['Playful',
'Affectionate',
'Keen',
'Sociable',
'Lively',
'Alert',
'Easygoing',
'Patient',
'Athletic',
'Bright'],
'type_of_pet': 'dog',
'weight': {'imperial': '28', 'metric': '13'}}
{'_id': ObjectId('67ed6529b16d68169fd97098'),
'bred_for': 'Watchdog, Hunting vermin on the farm.',
'breed': 'German Pinscher',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 20', 'metric': '43 - 51'},
'id': 114,
'life_span': '12-14',
'origin': [],
'temperament': ['Spirited',
'Lively',
'Intelligent',
'Loving',
'Even Tempered',
'Familial'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 45', 'metric': '11 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd97099'),
'bred_for': 'Herding, Guard dog',
'breed': 'German Shepherd Dog',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 26', 'metric': '56 - 66'},
'id': 115,
'life_span': '10-13',
'origin': [],
'temperament': ['Alert',
'Loyal',
'Obedient',
'Curious',
'Confident',
'Intelligent',
'Watchful',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 90', 'metric': '23 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9709a'),
'bred_for': 'General hunting',
'breed': 'German Shorthaired Pointer',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 25', 'metric': '53 - 64'},
'id': 116,
'life_span': '12-14',
'origin': [],
'temperament': ['Boisterous',
'Bold',
'Affectionate',
'Intelligent',
'Cooperative',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 70', 'metric': '20 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd9709b'),
'bred_for': 'Herding, guarding',
'breed': 'Giant Schnauzer',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '23.5 - 27.5', 'metric': '60 - 70'},
'id': 119,
'life_span': '10-12',
'origin': [],
'temperament': ['Strong Willed',
'Kind',
'Loyal',
'Intelligent',
'Dominant',
'Powerful'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 - 90', 'metric': '29 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd9709c'),
'bred_for': 'Rid the home and farm of vermin, and hunt badger and fox',
'breed': 'Glen of Imaal Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '12.5 - 14', 'metric': '32 - 36'},
'id': 120,
'life_span': '12-15',
'origin': [],
'temperament': ['Spirited',
'Agile',
'Loyal',
'Gentle',
'Active',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '32 - 40', 'metric': '15 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd9709d'),
'bred_for': 'Retrieving',
'breed': 'Golden Retriever',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21.5 - 24', 'metric': '55 - 61'},
'id': 121,
'life_span': '10-12',
'origin': [],
'temperament': ['Intelligent',
'Kind',
'Reliable',
'Friendly',
'Trustworthy',
'Confident'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 75', 'metric': '25 - 34'}}
{'_id': ObjectId('67ed6529b16d68169fd9709e'),
'bred_for': 'Find and point gamebirds',
'breed': 'Gordon Setter',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
'id': 123,
'life_span': '10-12',
'origin': [],
'temperament': ['Fearless', 'Alert', 'Loyal', 'Confident', 'Gay', 'Eager'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd9709f'),
'bred_for': 'Hunting & holding boars, Guardian',
'breed': 'Great Dane',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '28 - 32', 'metric': '71 - 81'},
'id': 124,
'life_span': '7-10',
'origin': [],
'temperament': ['Friendly',
'Devoted',
'Reserved',
'Gentle',
'Confident',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '110 - 190', 'metric': '50 - 86'}}
{'_id': ObjectId('67ed6529b16d68169fd970a0'),
'bred_for': 'Sheep guardian',
'breed': 'Great Pyrenees',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '25 - 32', 'metric': '64 - 81'},
'id': 125,
'life_span': '10-12',
'origin': [],
'temperament': ['Strong Willed',
'Fearless',
'Affectionate',
'Patient',
'Gentle',
'Confident'],
'type_of_pet': 'dog',
'weight': {'imperial': '85 - 115', 'metric': '39 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd970a1'),
'bred_for': 'Coursing hares',
'breed': 'Greyhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '27 - 30', 'metric': '69 - 76'},
'id': 127,
'life_span': '10-13',
'origin': [],
'temperament': ['Affectionate',
'Athletic',
'Gentle',
'Intelligent',
'Quiet',
'Even Tempered'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 70', 'metric': '23 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970a2'),
'bred_for': 'Hunt and kill vermin in stables',
'breed': 'Griffon Bruxellois',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
'id': 128,
'life_span': '10-15',
'origin': [],
'temperament': ['Self-important',
'Inquisitive',
'Alert',
'Companionable',
'Sensitive',
'Watchful'],
'type_of_pet': 'dog',
'weight': {'imperial': '12', 'metric': '5'}}
{'_id': ObjectId('67ed6529b16d68169fd970a3'),
'bred_for': 'Hunting hares by trailing them',
'breed': 'Harrier',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
'id': 129,
'life_span': '12-15',
'origin': [],
'temperament': ['Outgoing',
'Friendly',
'Cheerful',
'Sweet-Tempered',
'Tolerant',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970a4'),
'bred_for': 'Companionship',
'breed': 'Havanese',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8.5 - 11.5', 'metric': '22 - 29'},
'id': 130,
'life_span': '14-15',
'origin': [],
'temperament': ['Affectionate',
'Responsive',
'Playful',
'Companionable',
'Gentle',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '7 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd970a5'),
'bred_for': 'Bird setting, retrieving',
'breed': 'Irish Setter',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
'id': 134,
'life_span': '10-11',
'origin': [],
'temperament': ['Affectionate',
'Energetic',
'Lively',
'Independent',
'Playful',
'Companionable'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 70', 'metric': '16 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970a6'),
'bred_for': '',
'breed': 'Irish Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '18', 'metric': '46'},
'id': 135,
'life_span': '12-16',
'origin': [],
'temperament': ['Respectful',
'Lively',
'Intelligent',
'Dominant',
'Protective',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 27', 'metric': '11 - 12'}}
{'_id': ObjectId('67ed6529b16d68169fd970a7'),
'bred_for': 'Coursing wolves, elk',
'breed': 'Irish Wolfhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '30 - 35', 'metric': '76 - 89'},
'id': 137,
'life_span': '6-8',
'origin': [],
'temperament': ['Sweet-Tempered',
'Loyal',
'Dignified',
'Patient',
'Thoughtful',
'Generous'],
'type_of_pet': 'dog',
'weight': {'imperial': '105 - 180', 'metric': '48 - 82'}}
{'_id': ObjectId('67ed6529b16d68169fd970a8'),
'bred_for': 'Lapdog',
'breed': 'Italian Greyhound',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 15', 'metric': '33 - 38'},
'id': 138,
'life_span': '12-15',
'origin': [],
'temperament': ['Mischievous',
'Affectionate',
'Agile',
'Athletic',
'Companionable',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '7 - 15', 'metric': '3 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970a9'),
'bred_for': 'Lapdog',
'breed': 'Japanese Chin',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
'id': 140,
'life_span': '12-14',
'origin': [],
'temperament': ['Alert',
'Loyal',
'Independent',
'Intelligent',
'Loving',
'Cat-like'],
'type_of_pet': 'dog',
'weight': {'imperial': '4 - 9', 'metric': '2 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970aa'),
'bred_for': 'Companion',
'breed': 'Japanese Spitz',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '12 - 15', 'metric': '30 - 38'},
'id': 141,
'life_span': '10-16',
'origin': [],
'temperament': ['Affectionate',
'Obedient',
'Playful',
'Companionable',
'Intelligent',
'Proud'],
'type_of_pet': 'dog',
'weight': {'imperial': '15 - 19', 'metric': '7 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970ab'),
'bred_for': 'Barge watchdog',
'breed': 'Keeshond',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 18', 'metric': '43 - 46'},
'id': 142,
'life_span': '12-15',
'origin': [],
'temperament': ['Agile', 'Obedient', 'Playful', 'Quick', 'Sturdy', 'Bright'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 45', 'metric': '16 - 20'}}
{'_id': ObjectId('67ed6529b16d68169fd970ac'),
'bred_for': 'Sheep guardian',
'breed': 'Komondor',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '25.5 - 27.5', 'metric': '65 - 70'},
'id': 144,
'life_span': '10-12',
'origin': [],
'temperament': ['Steady',
'Fearless',
'Affectionate',
'Independent',
'Gentle',
'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '80 - 100', 'metric': '36 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd970ad'),
'bred_for': 'Luring ducks into traps - "tolling"',
'breed': 'Kooikerhondje',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 16', 'metric': '36 - 41'},
'id': 145,
'life_span': '12-15',
'origin': [],
'temperament': ['Benevolent',
'Agile',
'Alert',
'Intelligent',
'Active',
'Territorial'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970ae'),
'bred_for': 'Guardian, hunting large game',
'breed': 'Kuvasz',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '26 - 30', 'metric': '66 - 76'},
'id': 147,
'life_span': '8-10',
'origin': [],
'temperament': ['Clownish',
'Loyal',
'Patient',
'Independent',
'Intelligent',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '70 - 115', 'metric': '32 - 52'}}
{'_id': ObjectId('67ed6529b16d68169fd970af'),
'bred_for': 'Water retrieving',
'breed': 'Labrador Retriever',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21.5 - 24.5', 'metric': '55 - 62'},
'id': 149,
'life_span': '10-13',
'origin': [],
'temperament': ['Kind',
'Outgoing',
'Agile',
'Gentle',
'Intelligent',
'Trusting',
'Even Tempered'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 80', 'metric': '25 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970b0'),
'bred_for': 'Water retrieval dog in the marshes of Romagna',
'breed': 'Lagotto Romagnolo',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 19', 'metric': '41 - 48'},
'id': 151,
'life_span': '14-16',
'origin': [],
'temperament': ['Keen',
'Loyal',
'Companionable',
'Loving',
'Active',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '24 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970b1'),
'bred_for': 'Cattle herding, Ratting, Driving cattle to market.',
'breed': 'Lancashire Heeler',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
'id': 153,
'life_span': '12-15',
'origin': [],
'temperament': ['Clever', 'Friendly', 'Alert', 'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '6 - 13', 'metric': '3 - 6'}}
{'_id': ObjectId('67ed6529b16d68169fd970b2'),
'bred_for': 'Guardian, appearance.',
'breed': 'Leonberger',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '25.5 - 31.5', 'metric': '65 - 80'},
'id': 155,
'life_span': '6-8',
'origin': [],
'temperament': ['Obedient',
'Fearless',
'Loyal',
'Companionable',
'Adaptable',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '120 - 170', 'metric': '54 - 77'}}
{'_id': ObjectId('67ed6529b16d68169fd970b3'),
'bred_for': 'Guarding inside the home, companion',
'breed': 'Lhasa Apso',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
'id': 156,
'life_span': '12-15',
'origin': [],
'temperament': ['Steady',
'Fearless',
'Friendly',
'Devoted',
'Assertive',
'Spirited',
'Energetic',
'Lively',
'Alert',
'Obedient',
'Playful',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '12 - 18', 'metric': '5 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970b4'),
'bred_for': 'Lapdog',
'breed': 'Maltese',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 10', 'metric': '20 - 25'},
'id': 161,
'life_span': '15-18',
'origin': [],
'temperament': ['Playful',
'Docile',
'Fearless',
'Affectionate',
'Sweet-Tempered',
'Lively',
'Responsive',
'Easygoing',
'Gentle',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '4 - 7', 'metric': '2 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970b5'),
'bred_for': '',
'breed': 'Miniature American Shepherd',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 18', 'metric': '33 - 46'},
'id': 165,
'life_span': '12-15',
'origin': [],
'temperament': ['Energetic', 'Loyal', 'Intelligent', 'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 40', 'metric': '9 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd970b6'),
'bred_for': 'Small vermin hunting',
'breed': 'Miniature Pinscher',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 12.5', 'metric': '25 - 32'},
'id': 167,
'life_span': '15-15',
'origin': [],
'temperament': ['Clever',
'Outgoing',
'Friendly',
'Energetic',
'Responsive',
'Playful'],
'type_of_pet': 'dog',
'weight': {'imperial': '8 - 11', 'metric': '4 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970b7'),
'bred_for': 'Ratting',
'breed': 'Miniature Schnauzer',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '12 - 14', 'metric': '30 - 36'},
'id': 168,
'life_span': '12-14',
'origin': [],
'temperament': ['Fearless',
'Friendly',
'Spirited',
'Alert',
'Obedient',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '11 - 20', 'metric': '5 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970b8'),
'bred_for': 'All purpose water dog, fishing aid',
'breed': 'Newfoundland',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '26 - 28', 'metric': '66 - 71'},
'id': 171,
'life_span': '8-10',
'origin': [],
'temperament': ['Sweet-Tempered', 'Gentle', 'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '100 - 150', 'metric': '45 - 68'}}
{'_id': ObjectId('67ed6529b16d68169fd970b9'),
'bred_for': 'Ratting, fox bolting',
'breed': 'Norfolk Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
'id': 172,
'life_span': '12-15',
'origin': [],
'temperament': ['Self-confidence',
'Fearless',
'Spirited',
'Companionable',
'Happy',
'Lovable'],
'type_of_pet': 'dog',
'weight': {'imperial': '11 - 12', 'metric': '5 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970ba'),
'bred_for': 'Ratting, fox bolting',
'breed': 'Norwich Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '10', 'metric': '25'},
'id': 176,
'life_span': '12-15',
'origin': [],
'temperament': ['Hardy',
'Affectionate',
'Energetic',
'Sensitive',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '11 - 12', 'metric': '5 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970bb'),
'bred_for': '',
'breed': 'Nova Scotia Duck Tolling Retriever',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 21', 'metric': '43 - 53'},
'id': 177,
'life_span': '12-14',
'origin': [],
'temperament': ['Outgoing', 'Alert', 'Patient', 'Intelligent', 'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 50', 'metric': '16 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970bc'),
'bred_for': 'Driving sheep, cattle',
'breed': 'Old English Sheepdog',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '21', 'metric': '53'},
'id': 178,
'life_span': '10-12',
'origin': [],
'temperament': ['Sociable',
'Bubbly',
'Playful',
'Adaptable',
'Intelligent',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '60 - 100', 'metric': '27 - 45'}}
{'_id': ObjectId('67ed6529b16d68169fd970bd'),
'bred_for': '',
'breed': 'Olde English Bulldogge',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '15 - 19', 'metric': '38 - 48'},
'id': 179,
'life_span': '9-14',
'origin': [],
'temperament': ['Friendly',
'Alert',
'Confident',
'Loving',
'Courageous',
'Strong'],
'type_of_pet': 'dog',
'weight': {'imperial': '65 ā 85', 'metric': 'NaN'}}
{'_id': ObjectId('67ed6529b16d68169fd970be'),
'bred_for': 'Lapdog',
'breed': 'Papillon',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
'id': 181,
'life_span': '13-17',
'origin': [],
'temperament': ['Hardy',
'Friendly',
'Energetic',
'Alert',
'Intelligent',
'Happy'],
'type_of_pet': 'dog',
'weight': {'imperial': '3 - 12', 'metric': '1 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970bf'),
'bred_for': 'Lapdog',
'breed': 'Pekingese',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '6 - 9', 'metric': '15 - 23'},
'id': 183,
'life_span': '14-18',
'origin': [],
'temperament': ['Opinionated',
'Good-natured',
'Stubborn',
'Affectionate',
'Aggressive',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '14', 'metric': '6'}}
{'_id': ObjectId('67ed6529b16d68169fd970c0'),
'bred_for': 'Driving stock to market in northern Wales',
'breed': 'Pembroke Welsh Corgi',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
'id': 184,
'life_span': '12-14',
'origin': [],
'temperament': ['Tenacious',
'Outgoing',
'Friendly',
'Bold',
'Playful',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 30', 'metric': '11 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970c1'),
'bred_for': '',
'breed': 'Perro de Presa Canario',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 25.5', 'metric': '56 - 65'},
'id': 185,
'life_span': '10-12',
'origin': [],
'temperament': ['Strong Willed', 'Suspicious', 'Gentle', 'Dominant', 'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '88 - 110', 'metric': '40 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd970c2'),
'bred_for': 'Hunting rabbits',
'breed': 'Pharaoh Hound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 25', 'metric': '53 - 64'},
'id': 188,
'life_span': '12-14',
'origin': [],
'temperament': ['Affectionate',
'Sociable',
'Playful',
'Intelligent',
'Active',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970c3'),
'bred_for': 'Hunting big-game like Boar.',
'breed': 'Plott',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 25', 'metric': '51 - 64'},
'id': 189,
'life_span': '12-14',
'origin': [],
'temperament': ['Bold', 'Alert', 'Loyal', 'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '40 - 60', 'metric': '18 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970c4'),
'bred_for': 'Companion',
'breed': 'Pomeranian',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 12', 'metric': '20 - 30'},
'id': 193,
'life_span': '15-15',
'origin': [],
'temperament': ['Extroverted',
'Friendly',
'Sociable',
'Playful',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '3 - 7', 'metric': '1 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970c5'),
'bred_for': '',
'breed': 'Poodle (Miniature)',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '11 - 15', 'metric': '28 - 38'},
'id': 196,
'life_span': '12-15',
'origin': [],
'temperament': [''],
'type_of_pet': 'dog',
'weight': {'imperial': '15 - 17', 'metric': '7 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970c6'),
'bred_for': '',
'breed': 'Poodle (Toy)',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 11', 'metric': '23 - 28'},
'id': 197,
'life_span': '18-18',
'origin': [],
'temperament': [''],
'type_of_pet': 'dog',
'weight': {'imperial': '6 - 9', 'metric': '3 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970c7'),
'bred_for': 'Lapdog',
'breed': 'Pug',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 12', 'metric': '25 - 30'},
'id': 201,
'life_span': '12-14',
'origin': [],
'temperament': ['Docile',
'Clever',
'Charming',
'Stubborn',
'Sociable',
'Playful',
'Quiet',
'Attentive'],
'type_of_pet': 'dog',
'weight': {'imperial': '14 - 18', 'metric': '6 - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970c8'),
'bred_for': 'Herding',
'breed': 'Puli',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 17', 'metric': '41 - 43'},
'id': 204,
'life_span': '12-16',
'origin': [],
'temperament': ['Energetic',
'Agile',
'Loyal',
'Obedient',
'Intelligent',
'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970c9'),
'bred_for': '',
'breed': 'Pumi',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '15 - 18.5', 'metric': '38 - 47'},
'id': 205,
'life_span': '13-15',
'origin': [],
'temperament': ['Lively',
'Reserved',
'Intelligent',
'Active',
'Protective',
'Vocal'],
'type_of_pet': 'dog',
'weight': {'imperial': '18 - 33', 'metric': '8 - 15'}}
{'_id': ObjectId('67ed6529b16d68169fd970ca'),
'bred_for': '',
'breed': 'Rat Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 13', 'metric': '25 - 33'},
'id': 207,
'life_span': '12-18',
'origin': [],
'temperament': ['Affectionate',
'Lively',
'Inquisitive',
'Alert',
'Intelligent',
'Loving'],
'type_of_pet': 'dog',
'weight': {'imperial': '8 - 25', 'metric': '4 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd970cb'),
'bred_for': 'Hunting raccoon, deer, bear, and cougar.',
'breed': 'Redbone Coonhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 27', 'metric': '53 - 69'},
'id': 208,
'life_span': '10-12',
'origin': [],
'temperament': ['Affectionate',
'Energetic',
'Independent',
'Companionable',
'Familial',
'Unflappable'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970cc'),
'bred_for': 'Big game hunting, guarding',
'breed': 'Rhodesian Ridgeback',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 27', 'metric': '61 - 69'},
'id': 209,
'life_span': '10-12',
'origin': [],
'temperament': ['Strong Willed',
'Mischievous',
'Loyal',
'Dignified',
'Sensitive',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '75 - 80', 'metric': '34 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970cd'),
'bred_for': 'Cattle drover, guardian, draft',
'breed': 'Rottweiler',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 27', 'metric': '56 - 69'},
'id': 210,
'life_span': '8-10',
'origin': [],
'temperament': ['Steady',
'Good-natured',
'Fearless',
'Devoted',
'Alert',
'Obedient',
'Confident',
'Self-assured',
'Calm',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '75 - 110', 'metric': '34 - 50'}}
{'_id': ObjectId('67ed6529b16d68169fd970ce'),
'bred_for': '',
'breed': 'Russian Toy',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '7.5 - 10.5', 'metric': '19 - 27'},
'id': 211,
'life_span': '10-12',
'origin': [],
'temperament': [''],
'type_of_pet': 'dog',
'weight': {'imperial': '3 - 6', 'metric': '1 - 3'}}
{'_id': ObjectId('67ed6529b16d68169fd970cf'),
'bred_for': 'Draft, search, rescue',
'breed': 'Saint Bernard',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '25.5 - 27.5', 'metric': '65 - 70'},
'id': 212,
'life_span': '7-10',
'origin': [],
'temperament': ['Friendly', 'Lively', 'Gentle', 'Watchful', 'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '130 - 180', 'metric': '59 - 82'}}
{'_id': ObjectId('67ed6529b16d68169fd970d0'),
'bred_for': 'Coursing gazelle and hare',
'breed': 'Saluki',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 28', 'metric': '58 - 71'},
'id': 213,
'life_span': '12-14',
'origin': [],
'temperament': ['Aloof', 'Reserved', 'Intelligent', 'Quiet'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 65', 'metric': '16 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970d1'),
'bred_for': 'Herding reindeer, guardian, draft',
'breed': 'Samoyed',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '19 - 23.5', 'metric': '48 - 60'},
'id': 214,
'life_span': '12-14',
'origin': [],
'temperament': ['Stubborn',
'Friendly',
'Sociable',
'Lively',
'Alert',
'Playful'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 60', 'metric': '23 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970d2'),
'bred_for': 'Barge watchdog',
'breed': 'Schipperke',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 13', 'metric': '25 - 33'},
'id': 216,
'life_span': '13-15',
'origin': [],
'temperament': ['Fearless',
'Agile',
'Curious',
'Independent',
'Confident',
'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '10 - 16', 'metric': '5 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970d3'),
'bred_for': 'Coursing deer',
'breed': 'Scottish Deerhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '28 - 32', 'metric': '71 - 81'},
'id': 218,
'life_span': '8-10',
'origin': [],
'temperament': ['Docile', 'Friendly', 'Dignified', 'Gentle'],
'type_of_pet': 'dog',
'weight': {'imperial': '70 - 130', 'metric': '32 - 59'}}
{'_id': ObjectId('67ed6529b16d68169fd970d4'),
'bred_for': 'Vermin hunting',
'breed': 'Scottish Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '10', 'metric': '25'},
'id': 219,
'life_span': '11-13',
'origin': [],
'temperament': ['Feisty',
'Alert',
'Independent',
'Playful',
'Quick',
'Self-assured'],
'type_of_pet': 'dog',
'weight': {'imperial': '18 - 22', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970d5'),
'bred_for': 'Sheep herding',
'breed': 'Shetland Sheepdog',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 16', 'metric': '33 - 41'},
'id': 221,
'life_span': '12-14',
'origin': [],
'temperament': ['Affectionate',
'Lively',
'Responsive',
'Alert',
'Loyal',
'Reserved',
'Playful',
'Gentle',
'Intelligent',
'Active',
'Trainable',
'Strong'],
'type_of_pet': 'dog',
'weight': {'imperial': '30', 'metric': '14'}}
{'_id': ObjectId('67ed6529b16d68169fd970d6'),
'bred_for': 'Hunting in the mountains of Japan, Alert Watchdog',
'breed': 'Shiba Inu',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '13.5 - 16.5', 'metric': '34 - 42'},
'id': 222,
'life_span': '12-16',
'origin': [],
'temperament': ['Charming',
'Fearless',
'Keen',
'Alert',
'Confident',
'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '17 - 23', 'metric': '8 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970d7'),
'bred_for': 'Lapdog',
'breed': 'Shih Tzu',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
'id': 223,
'life_span': '10-18',
'origin': [],
'temperament': ['Clever',
'Spunky',
'Outgoing',
'Friendly',
'Affectionate',
'Lively',
'Alert',
'Loyal',
'Independent',
'Playful',
'Gentle',
'Intelligent',
'Happy',
'Active',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '9 - 16', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970d8'),
'bred_for': 'Swimming, Carrying backpacks, Pulling carts or sleds',
'breed': 'Shiloh Shepherd',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '26 - 30', 'metric': '66 - 76'},
'id': 225,
'life_span': '9-14',
'origin': [],
'temperament': ['Outgoing',
'Loyal',
'Companionable',
'Gentle',
'Loving',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '120 - 140', 'metric': '54 - 64'}}
{'_id': ObjectId('67ed6529b16d68169fd970d9'),
'bred_for': 'Sled pulling',
'breed': 'Siberian Husky',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 23.5', 'metric': '51 - 60'},
'id': 226,
'life_span': '12-12',
'origin': [],
'temperament': ['Outgoing', 'Friendly', 'Alert', 'Gentle', 'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 60', 'metric': '16 - 27'}}
{'_id': ObjectId('67ed6529b16d68169fd970da'),
'bred_for': 'Small vermin hunting, companionship',
'breed': 'Silky Terrier',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '9 - 10', 'metric': '23 - 25'},
'id': 228,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly',
'Responsive',
'Inquisitive',
'Alert',
'Quick',
'Joyful'],
'type_of_pet': 'dog',
'weight': {'imperial': '8 - 10', 'metric': '4 - 5'}}
{'_id': ObjectId('67ed6529b16d68169fd970db'),
'bred_for': 'Fox bolting',
'breed': 'Smooth Fox Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '15.5', 'metric': '39'},
'id': 232,
'life_span': '12-14',
'origin': [],
'temperament': ['Fearless',
'Affectionate',
'Alert',
'Playful',
'Intelligent',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': 'up - 18', 'metric': 'NaN - 8'}}
{'_id': ObjectId('67ed6529b16d68169fd970dc'),
'bred_for': 'Vermin hunting, guarding, all-around farm helper',
'breed': 'Soft Coated Wheaten Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 18', 'metric': '41 - 46'},
'id': 233,
'life_span': '12-15',
'origin': [],
'temperament': ['Affectionate',
'Spirited',
'Energetic',
'Playful',
'Intelligent',
'Faithful'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 40', 'metric': '14 - 18'}}
{'_id': ObjectId('67ed6529b16d68169fd970dd'),
'bred_for': 'Herding flocks of sheep and goats from one pasture to another',
'breed': 'Spanish Water Dog',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '16 - 20', 'metric': '41 - 51'},
'id': 235,
'life_span': '12-15',
'origin': [],
'temperament': ['Trainable',
'Diligent',
'Affectionate',
'Loyal',
'Athletic',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 50', 'metric': '14 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970de'),
'bred_for': '',
'breed': 'Spinone Italiano',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '22.5 - 27.5', 'metric': '57 - 70'},
'id': 236,
'life_span': '10-12',
'origin': [],
'temperament': ['Docile',
'Friendly',
'Affectionate',
'Loyal',
'Patient',
'Gentle'],
'type_of_pet': 'dog',
'weight': {'imperial': '61 - 85', 'metric': '28 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd970df'),
'bred_for': '',
'breed': 'Staffordshire Bull Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 16', 'metric': '36 - 41'},
'id': 238,
'life_span': '12-14',
'origin': [],
'temperament': ['Reliable',
'Fearless',
'Bold',
'Affectionate',
'Loyal',
'Intelligent',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '24 - 38', 'metric': '11 - 17'}}
{'_id': ObjectId('67ed6529b16d68169fd970e0'),
'bred_for': 'Ratting, guarding',
'breed': 'Standard Schnauzer',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '17.5 - 19.5', 'metric': '44 - 50'},
'id': 239,
'life_span': '13-15',
'origin': [],
'temperament': ['Trainable',
'Good-natured',
'Devoted',
'Lively',
'Playful',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '30 - 50', 'metric': '14 - 23'}}
{'_id': ObjectId('67ed6529b16d68169fd970e1'),
'bred_for': '',
'breed': 'Swedish Vallhund',
'breed_group': 'Herding',
'country_code': '',
'geocord': '',
'height': {'imperial': '11.5 - 13.5', 'metric': '29 - 34'},
'id': 242,
'life_span': '12-14',
'origin': [],
'temperament': ['Fearless',
'Friendly',
'Energetic',
'Alert',
'Intelligent',
'Watchful'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 30', 'metric': '9 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970e2'),
'bred_for': '',
'breed': 'Thai Ridgeback',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 24', 'metric': '51 - 61'},
'id': 243,
'life_span': '10-12',
'origin': [],
'temperament': ['Protective',
'Loyal',
'Independent',
'Intelligent',
'Loving',
'Familial'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 55', 'metric': '16 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd970e3'),
'bred_for': '',
'breed': 'Tibetan Mastiff',
'breed_group': 'Working',
'country_code': '',
'geocord': '',
'height': {'imperial': '24 - 26', 'metric': '61 - 66'},
'id': 244,
'life_span': '10-14',
'origin': [],
'temperament': ['Strong Willed',
'Tenacious',
'Aloof',
'Stubborn',
'Intelligent',
'Protective'],
'type_of_pet': 'dog',
'weight': {'imperial': '85 - 140', 'metric': '39 - 64'}}
{'_id': ObjectId('67ed6529b16d68169fd970e4'),
'bred_for': '',
'breed': 'Tibetan Spaniel',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '10', 'metric': '25'},
'id': 245,
'life_span': '12-15',
'origin': [],
'temperament': ['Willful',
'Aloof',
'Assertive',
'Independent',
'Playful',
'Intelligent',
'Happy'],
'type_of_pet': 'dog',
'weight': {'imperial': '9 - 15', 'metric': '4 - 7'}}
{'_id': ObjectId('67ed6529b16d68169fd970e5'),
'bred_for': 'Good luck charms, mascots, watchdogs, herding dogs, and '
'companions',
'breed': 'Tibetan Terrier',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '14 - 17', 'metric': '36 - 43'},
'id': 246,
'life_span': '12-15',
'origin': [],
'temperament': ['Affectionate',
'Energetic',
'Amiable',
'Reserved',
'Gentle',
'Sensitive'],
'type_of_pet': 'dog',
'weight': {'imperial': '20 - 24', 'metric': '9 - 11'}}
{'_id': ObjectId('67ed6529b16d68169fd970e6'),
'bred_for': '',
'breed': 'Toy Fox Terrier',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 11', 'metric': '20 - 28'},
'id': 248,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly',
'Spirited',
'Alert',
'Loyal',
'Playful',
'Intelligent'],
'type_of_pet': 'dog',
'weight': {'imperial': '4 - 9', 'metric': '2 - 4'}}
{'_id': ObjectId('67ed6529b16d68169fd970e7'),
'bred_for': '',
'breed': 'Treeing Walker Coonhound',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 27', 'metric': '51 - 69'},
'id': 250,
'life_span': '10-13',
'origin': [],
'temperament': ['Clever',
'Affectionate',
'Confident',
'Intelligent',
'Loving',
'Trainable'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 80', 'metric': '20 - 36'}}
{'_id': ObjectId('67ed6529b16d68169fd970e8'),
'bred_for': 'Pointing and trailing',
'breed': 'Vizsla',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21 - 24', 'metric': '53 - 61'},
'id': 251,
'life_span': '10-14',
'origin': [],
'temperament': ['Affectionate', 'Energetic', 'Loyal', 'Gentle', 'Quiet'],
'type_of_pet': 'dog',
'weight': {'imperial': '50 - 65', 'metric': '23 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970e9'),
'bred_for': 'Large game trailing and versatile gundog',
'breed': 'Weimaraner',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '23 - 27', 'metric': '58 - 69'},
'id': 253,
'life_span': '12-15',
'origin': [],
'temperament': ['Steady',
'Aloof',
'Stubborn',
'Energetic',
'Alert',
'Intelligent',
'Powerful',
'Fast'],
'type_of_pet': 'dog',
'weight': {'imperial': '55 - 90', 'metric': '25 - 41'}}
{'_id': ObjectId('67ed6529b16d68169fd970ea'),
'bred_for': 'Flushing and retrieving birds',
'breed': 'Welsh Springer Spaniel',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '17 - 19', 'metric': '43 - 48'},
'id': 254,
'life_span': '12-15',
'origin': [],
'temperament': ['Stubborn',
'Friendly',
'Affectionate',
'Loyal',
'Playful',
'Active'],
'type_of_pet': 'dog',
'weight': {'imperial': '35 - 55', 'metric': '16 - 25'}}
{'_id': ObjectId('67ed6529b16d68169fd970eb'),
'bred_for': 'Fox, badger, vermin hunting',
'breed': 'West Highland White Terrier',
'breed_group': 'Terrier',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 11', 'metric': '25 - 28'},
'id': 256,
'life_span': '15-20',
'origin': [],
'temperament': ['Hardy',
'Friendly',
'Alert',
'Independent',
'Gay',
'Active',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '15 - 22', 'metric': '7 - 10'}}
{'_id': ObjectId('67ed6529b16d68169fd970ec'),
'bred_for': 'Coursing, racing',
'breed': 'Whippet',
'breed_group': 'Hound',
'country_code': '',
'geocord': '',
'height': {'imperial': '18 - 22', 'metric': '46 - 56'},
'id': 257,
'life_span': '12-15',
'origin': [],
'temperament': ['Friendly',
'Affectionate',
'Lively',
'Gentle',
'Intelligent',
'Quiet'],
'type_of_pet': 'dog',
'weight': {'imperial': '25 - 35', 'metric': '11 - 16'}}
{'_id': ObjectId('67ed6529b16d68169fd970ed'),
'bred_for': '',
'breed': 'White Shepherd',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '22 - 25', 'metric': '56 - 64'},
'id': 258,
'life_span': '12-14',
'origin': [],
'temperament': ['Self-confidence',
'Aloof',
'Fearless',
'Alert',
'Companionable',
'Eager'],
'type_of_pet': 'dog',
'weight': {'imperial': '60 - 85', 'metric': '27 - 39'}}
{'_id': ObjectId('67ed6529b16d68169fd970ee'),
'bred_for': 'Vermin hunting, fox bolting',
'breed': 'Wire Fox Terrier',
'breed_group': '',
'country_code': '',
'geocord': '',
'height': {'imperial': '13 - 16', 'metric': '33 - 41'},
'id': 259,
'life_span': '13-14',
'origin': [],
'temperament': ['Fearless', 'Friendly', 'Bold', 'Keen', 'Alert', 'Quick'],
'type_of_pet': 'dog',
'weight': {'imperial': '15 - 19', 'metric': '7 - 9'}}
{'_id': ObjectId('67ed6529b16d68169fd970ef'),
'bred_for': 'Gundog, "swamp-tromping", Flushing, pointing, and retrieving '
'water fowl & game birds',
'breed': 'Wirehaired Pointing Griffon',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '20 - 24', 'metric': '51 - 61'},
'id': 260,
'life_span': '12-14',
'origin': [],
'temperament': ['Loyal', 'Gentle', 'Vigilant', 'Trainable', 'Proud'],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 70', 'metric': '20 - 32'}}
{'_id': ObjectId('67ed6529b16d68169fd970f0'),
'bred_for': '',
'breed': 'Wirehaired Vizsla',
'breed_group': 'Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '21.5 - 25', 'metric': '55 - 64'},
'id': 261,
'life_span': '12-14',
'origin': [],
'temperament': [''],
'type_of_pet': 'dog',
'weight': {'imperial': '45 - 65', 'metric': '20 - 29'}}
{'_id': ObjectId('67ed6529b16d68169fd970f1'),
'bred_for': '',
'breed': 'Xoloitzcuintli',
'breed_group': 'Non-Sporting',
'country_code': '',
'geocord': '',
'height': {'imperial': '10 - 23', 'metric': '25 - 58'},
'id': 262,
'life_span': '12-14',
'origin': [],
'temperament': ['Cheerful',
'Alert',
'Companionable',
'Intelligent',
'Protective',
'Calm'],
'type_of_pet': 'dog',
'weight': {'imperial': '9 - 31', 'metric': '4 - 14'}}
{'_id': ObjectId('67ed6529b16d68169fd970f2'),
'bred_for': 'Small vermin hunting',
'breed': 'Yorkshire Terrier',
'breed_group': 'Toy',
'country_code': '',
'geocord': '',
'height': {'imperial': '8 - 9', 'metric': '20 - 23'},
'id': 264,
'life_span': '12-16',
'origin': [],
'temperament': ['Bold',
'Independent',
'Confident',
'Intelligent',
'Courageous'],
'type_of_pet': 'dog',
'weight': {'imperial': '4 - 7', 'metric': '2 - 3'}}
Selection of specific columns for better understanding of dataset
db = client["dogsdb"]
collection = db["type_dogs"]
# Query the collection with a projection and limit to 5 results
cursor = collection.find(
{},
{
"_id": 0,
"type_of_pet": 1,
"breed": 1,
"country_code": 1,
"origin": 1,
"geocord": 1,
"life_span": 1,
"weight": 1,
"temperament": 1,
"height": 1,
"breed_group": 1
}
).limit(10)
# Convert the cursor to a list, then create a DataFrame
data = list(cursor)
df = pd.DataFrame(data)
df
| type_of_pet | breed | origin | country_code | life_span | temperament | weight | height | breed_group | geocord | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | dog | Affenpinscher | [Germany, France] | 10-12 | [Stubborn, Curious, Playful, Adventurous, Acti... | {'imperial': '6 - 13', 'metric': '3 - 6'} | {'imperial': '9 - 11.5', 'metric': '23 - 29'} | Toy | {'lat': 51.1638175, 'lon': 10.4478313} | |
| 1 | dog | Afghan Hound | [Afghanistan, Iran, Pakistan] | AG | 10-13 | [Aloof, Clownish, Dignified, Independent, Happy] | {'imperial': '50 - 60', 'metric': '23 - 27'} | {'imperial': '25 - 27', 'metric': '64 - 69'} | Hound | {'lat': 33.7680065, 'lon': 66.2385139} |
| 2 | dog | African Hunting Dog | [] | 11-11 | [Wild, Hardworking, Dutiful] | {'imperial': '44 - 66', 'metric': '20 - 30'} | {'imperial': '30', 'metric': '76'} | |||
| 3 | dog | Airedale Terrier | [United Kingdom, England] | 10-13 | [Outgoing, Friendly, Alert, Confident, Intelli... | {'imperial': '40 - 65', 'metric': '18 - 29'} | {'imperial': '21 - 23', 'metric': '53 - 58'} | Terrier | {'lat': 54.7023545, 'lon': -3.2765753} | |
| 4 | dog | Akbash Dog | [] | 10-12 | [Loyal, Independent, Intelligent, Brave] | {'imperial': '90 - 120', 'metric': '41 - 54'} | {'imperial': '28 - 34', 'metric': '71 - 86'} | Working | ||
| 5 | dog | Akita | [] | 10-14 | [Docile, Alert, Responsive, Dignified, Compose... | {'imperial': '65 - 115', 'metric': '29 - 52'} | {'imperial': '24 - 28', 'metric': '61 - 71'} | Working | ||
| 6 | dog | Alapaha Blue Blood Bulldog | [] | 12-13 | [Loving, Protective, Trainable, Dutiful, Respo... | {'imperial': '55 - 90', 'metric': '25 - 41'} | {'imperial': '18 - 24', 'metric': '46 - 61'} | Mixed | ||
| 7 | dog | Alaskan Husky | [] | 10-13 | [Friendly, Energetic, Loyal, Gentle, Confident] | {'imperial': '38 - 50', 'metric': '17 - 23'} | {'imperial': '23 - 26', 'metric': '58 - 66'} | Mixed | ||
| 8 | dog | Alaskan Malamute | [] | 12-15 | [Friendly, Affectionate, Devoted, Loyal, Digni... | {'imperial': '65 - 100', 'metric': '29 - 45'} | {'imperial': '23 - 25', 'metric': '58 - 64'} | Working | ||
| 9 | dog | American Bulldog | [] | 10-12 | [Friendly, Assertive, Energetic, Loyal, Gentle... | {'imperial': '60 - 120', 'metric': '27 - 54'} | {'imperial': '22 - 27', 'metric': '56 - 69'} | Working |
db = client["catsdb"]
collection = db["type_cats"]
for pet in collection.find():
origin_field = pet.get("origin")
if not origin_field:
# Skip documents with no origin
continue
# If origin is a single string but may contain commas, split on the first comma
if isinstance(origin_field, str):
origin_field = origin_field.split(",")[0].strip()
# Query Nominatim for just this first origin
url = "https://nominatim.openstreetmap.org/search"
params = {
"country": origin_field,
"format": "json"
}
headers = {
"User-Agent": "MyAwesomeApp/1.0 (myemail@example.com)"
}
try:
response = requests.get(url, params=params, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
except requests.RequestException as e:
print(f"Request failed for origin '{origin_field}': {e}")
continue
# Update if the data list is not empty
if data:
try:
lat = float(data[0].get("lat", 0))
lon = float(data[0].get("lon", 0))
result = collection.update_one(
{"_id": pet["_id"]},
{"$set": {"geocord": {"lat": lat, "lon": lon}}}
)
if result.matched_count > 0:
print(f"Updated doc _id={pet['_id']} with lat={lat}, lon={lon}")
else:
print(f"No document matched for _id={pet['_id']}")
except (ValueError, KeyError) as e:
print(f"Failed to parse lat/lon for origin '{origin_field}': {e}")
else:
print(f"No results for origin '{origin_field}'")
time.sleep(1)
# Optional: Confirm an example
check_pet = collection.find_one({"_id": pet["_id"]})
print("Example updated pet with geocord:", check_pet.get("geocord"))
Updated doc _id=67ed652ab16d68169fd97122 with lat=39.7837304, lon=-100.445882
No results for origin '['Iran (Persia)']'
Updated doc _id=67ed652ab16d68169fd97124 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97125 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97126 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97127 with lat=64.6863136, lon=97.7453061
Updated doc _id=67ed652ab16d68169fd97128 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97129 with lat=54.7023545, lon=-3.2765753
Updated doc _id=67ed652ab16d68169fd9712a with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd9712b with lat=14.8971921, lon=100.83273
Updated doc _id=67ed652ab16d68169fd9712c with lat=64.6863136, lon=97.7453061
Updated doc _id=67ed652ab16d68169fd9712d with lat=1.357107, lon=103.8194992
Updated doc _id=67ed652ab16d68169fd9712e with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd9712f with lat=8.3676771, lon=49.083416
Updated doc _id=67ed652ab16d68169fd97130 with lat=61.0666922, lon=-107.991707
Updated doc _id=67ed652ab16d68169fd97131 with lat=61.0666922, lon=-107.991707
Updated doc _id=67ed652ab16d68169fd97132 with lat=39.7837304, lon=-100.445882
Updated doc _id=67ed652ab16d68169fd97133 with lat=39.294076, lon=35.2316631
Updated doc _id=67ed652ab16d68169fd97134 with lat=39.294076, lon=35.2316631
Updated doc _id=67ed652ab16d68169fd97135 with lat=39.7837304, lon=-100.445882
Example updated pet with geocord: {'lat': 39.7837304, 'lon': -100.445882}
Extracting origin from from type_cats collection, and adding coordinates to empty column 'geocord'¶
Selection of specific columns for better understanding of dataset¶
db = client["catsdb"]
collection = db["type_cats"]
# Query the collection with a projection
pipeline = collection.find(
{},
{
"_id": 0,
"type_of_pet": 1,
"breed": 1,
"country_code": 1,
"origin": 1,
"geocord": 1,
"life_span": 1,
"weight": 1,
"temperament": 1
}
).limit(5)
# Convert the pipeline to a list, then create a DataFrame
data = list(pipeline)
df = pd.DataFrame(data)
df
š Data Analysis¶
š¶ Dogs Database Collection¶
This section explores and analyzes the data stored in the type_dogs collection.
Key areas of focus include:
- Breed distribution
- Temperament traits
- Height and weight analysis
- Breed group statistics
- Geographic origin insights
Using aggregation pipelines and visualizations, we extract meaningful patterns and trends from the dataset.
To get the unique values of breed_group from your MongoDB collection, we can use the .distinct() method in PyMongo
š§ Intelligent Dog Breeds in the Sporting Group¶
This MongoDB aggregation pipeline retrieves dog breeds that are part of the Sporting group and have the "Intelligent" temperament.
𧩠Pipeline Breakdown¶
$match- Filters documents to include only those where:
"breed_group"is"Sporting""temperament"array contains the string"Intelligent"
- Filters documents to include only those where:
$project- Returns only selected fields:
breedbreed_grouptemperament
- Excludes the default
_idfield from the output.
- Returns only selected fields:
š Output¶
The result is a list of breeds that:
- Belong to the Sporting group, which includes active and energetic breeds often used for hunting or retrieving.
- Are described as Intelligent, suggesting quick learning and trainability.
This filtered list is useful for identifying smart, athletic dog breeds suited for active owners or working roles.
import pandas as pd
db = client["dogsdb"]
collection = db["type_dogs"]
pipeline = [
{
"$match": {
"breed_group": "Sporting",
"temperament": { "$regex": "Intelligent", "$options": "i" }
}
},
{
"$project": {
"_id": 0,
"breed_group": 1,
"breed": 1,
"temperament": 1
}
}
]
# Execute the aggregation pipeline
results = list(collection.aggregate(pipeline))
df1 = pd.DataFrame(results)
df1.head(6)
from wordcloud import WordCloud
import pandas as pd
import matplotlib.pyplot as plt
# Convert the results to a DataFrame
df1 = pd.DataFrame(results)
# Combine all breed names into a single string, separated by space
text = " ".join(df1['breed'].dropna().tolist())
# Create and display the word cloud
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud of Intelligent Breed Group Sporting')
plt.show()
šÆ Filtered List of Intelligent Sporting Breeds (Excluding Lapdogs)¶
This MongoDB aggregation pipeline is used to filter and display Sporting dog breeds that are known for being Intelligent, while specifically excluding those bred to be lapdogs.
š Pipeline Breakdown¶
$match- Filters documents where:
breed_groupis"Sporting"temperamentincludes"Intelligent"(searches within the array)bred_fordoes not contain the word"lapdog"(case-insensitive exclusion using$notwith$regex)
- Filters documents where:
$project- Selects and returns only the following fields:
breedbreed_grouptemperamentbred_for
- Omits the default
_idfield from the output.
- Selects and returns only the following fields:
š Output¶
The result is a curated list of breeds that:
- Belong to the Sporting group
- Are described as Intelligent
- Were not bred to be lapdogs
This helps narrow down active, intelligent breeds that are typically used for tasks like hunting, retrieving, or field work ā not just companionship.
import pandas as pd
db = client["dogsdb"]
pets_collection = db["type_dogs"]
# Aggregation pipeline
pipeline = [
{
"$match": {
"breed_group": "Sporting",
"temperament": "Intelligent",
"bred_for": {
"$not": {
"$regex": "lapdog",
"$options": "i"
}
}
}
},
{
"$project": {
"_id": 0,
"breed_group": 1,
"breed": 1,
"temperament": 1,
"bred_for": 1
}
}
]
# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df2 = pd.DataFrame(results)
# Display the first 6 results
df2.head(6)
from wordcloud import WordCloud
import pandas as pd
import matplotlib.pyplot as plt
# Convert the results to a DataFrame
df2 = pd.DataFrame(results)
# Combine all breed names into a single string, separated by space
text = " ".join(df2['breed'].dropna().tolist())
# Create and display the word cloud
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud of Intelligent Breed Group Sporting')
plt.show()
š¶ Top 10 Tallest Dog Breeds by Average Metric Height¶
This MongoDB aggregation pipeline retrieves the top 10 tallest dog breeds based on their average height in centimeters (height.metric field).
š Pipeline Breakdown¶
$project- Extracts the
breedfield. - Calculates a new field
avgMetricHeight:- Splits the string in
height.metric(e.g.,"23 - 29") into two values:["23", "29"]. - Converts them to numbers (
$toDouble). - Averages the two numbers using
$avg.
- Splits the string in
- Extracts the
$sort- Sorts all documents in descending order of
avgMetricHeight.
- Sorts all documents in descending order of
$limit- Limits the results to the top 10 breeds with the highest average height.
š Output¶
The result is a list of dog breeds and their respective average heights in metric units (cm), sorted from tallest to shortest.
Use this pipeline to quickly identify the largest breeds based on standardized height data!
from pymongo import MongoClient
import matplotlib.pyplot as plt
import numpy as np
db = client["dogsdb"]
collection = db["type_dogs"]
# Define the aggregation pipeline with $limit
pipeline = [
{
"$project": {
"breed": 1,
"avgMetricHeight": {
"$avg": {
"$map": {
"input": { "$split": ["$height.metric", " - "] },
"as": "h",
"in": { "$toDouble": "$$h" }
}
}
}
}
},
{
"$sort": { "avgMetricHeight": -1 }
},
{
"$limit": 10
}
]
# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df3 = pd.DataFrame(results)
# Display the first 10 results
df3.head(10)
# Extract data for plotting
breeds = [doc["breed"] for doc in results]
avg_heights = [doc["avgMetricHeight"] for doc in results]
# Prepare numeric y-axis for horizontal bar chart
y = np.arange(len(breeds))
colors = plt.cm.plasma(np.linspace(0, 1, len(breeds)))
# Create the horizontal bar chart
plt.figure(figsize=(10, 6))
plt.barh(y, avg_heights, color=colors)
plt.xlabel("Average Metric Height in cm")
plt.ylabel("Breed")
plt.title("Top 10 Tallest Dog Breeds by Average Metric Height")
plt.yticks(y, breeds)
plt.gca().invert_yaxis()
plt.tight_layout()
plt.show()
āļø Average Metric Weight by Dog Breed¶
This aggregation pipeline calculates and sorts dog breeds by their average weight (in kilograms) based on the weight.metric field.
š Pipeline Breakdown¶
$project- Keeps the
breedfield. - Creates
avgMetricWeightby:- Splitting the string in
weight.metric(e.g.,"3 - 6") into a list:["3", "6"] - Converting the values to numbers
- Calculating the average using
$avg
- Splitting the string in
- Keeps the
$sort- Sorts breeds in descending order by their
avgMetricWeight
- Sorts breeds in descending order by their
This helps identify the heaviest dog breeds based on average weight data.
# Define the aggregation pipeline
db = client["dogsdb"]
collection = db["type_dogs"]
# Define the aggregation pipeline with $limit
pipeline = [
{
"$project": {
"breed": 1,
"avgMetricWeight": {
"$avg": {
"$map": {
"input": { "$split": ["$weight.metric", " - "] },
"as": "w",
"in": { "$toDouble": "$$w" }
}
}
}
}
},
{
"$sort": { "avgMetricWeight": -1 }
},
{
"$limit": 20
}
]
# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df4 = pd.DataFrame(results)
# Display the first 10 results
df4.head(10)
# Extract data
breeds = [doc["breed"] for doc in results]
avg_weights = [doc["avgMetricWeight"] for doc in results]
# Prepare x-axis
x = np.arange(len(breeds))
colors = plt.cm.viridis(np.linspace(0, 1, len(breeds)))
# Create bar chart
plt.figure(figsize=(10, 6))
plt.bar(x, avg_weights, color=colors)
plt.xlabel("Breed")
plt.ylabel("Average Metric Weight in Kg")
plt.title("Top 20 Dog Breeds by Average Metric Weight")
plt.xticks(x, breeds, rotation=45, ha="right")
plt.tight_layout()
plt.show()
š Longevity Analysis: Dog Breeds with Long Life Expectancy¶
This pipeline filters dog breeds based on their upper life span, identifying breeds that typically live 13 years or more.
𧩠Pipeline Breakdown¶
$project- Keeps
breedandlife_spanfields. - Creates a new field
lifeSpanBoundsby:- Splitting the
life_spanstring (e.g.,"10-12") by"-"into a list. - Trimming whitespace from the resulting parts.
- Splitting the
- Keeps
Second
$project- Calculates
upperLifeSpan:- If the life span has a range (e.g.,
["10", "12"]), the second value is used. - If itās a single number (e.g.,
"14"), it uses that directly.
- If the life span has a range (e.g.,
- Calculates
$match- Filters only the breeds where
upperLifeSpanis 13 or greater.
- Filters only the breeds where
š Result¶
A refined list of dog breeds with relatively long life expectancy, useful for:
- Understanding breed longevity
- Informing adopters and pet owners
- Enriching data visualizations and statistics on dog health
# 1) Run the pipeline and convert results to a list
pipeline = [
{
"$project": {
"breed": 1,
"life_span": 1,
"cleanLifeSpan": {
"$replaceAll": {
"input": {
"$replaceAll": {
"input": "$life_span",
"find": " years",
"replacement": ""
}
},
"find": "-",
"replacement": " - "
}
}
}
},
{
"$project": {
"breed": 1,
"lifeSpanBounds": {
"$map": {
"input": { "$split": ["$cleanLifeSpan", " - "] },
"as": "bound",
"in": { "$trim": { "input": "$$bound" } }
}
}
}
},
{
"$project": {
"breed": 1,
"upperLifeSpan": {
"$cond": [
{ "$gte": [{ "$size": "$lifeSpanBounds" }, 2] },
{ "$toDouble": { "$arrayElemAt": ["$lifeSpanBounds", 1] } },
{ "$toDouble": { "$arrayElemAt": ["$lifeSpanBounds", 0] } }
]
}
}
},
{
"$match": {
"upperLifeSpan": { "$gte": 13 }
}
},
{
"$sort": { "upperLifeSpan": -1 }
},
{
"$limit": 10
}
]
# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df5 = pd.DataFrame(results)
# Display the first 10 results
df5.head(10)
import matplotlib.pyplot as plt
# Sort the correct DataFrame
df5_sorted = df5.sort_values(by="upperLifeSpan", ascending=False)
# Extract data for plotting
breeds = df5_sorted["breed"]
lifespans = df5_sorted["upperLifeSpan"]
# Create the plot
plt.figure(figsize=(10, 6))
plt.barh(breeds, lifespans, color=plt.cm.Paired.colors)
plt.xlabel("Upper Life Span (Years)")
plt.title("Top 10 Longest-Living Dog Breeds")
plt.gca().invert_yaxis() # Highest lifespan on top
plt.tight_layout()
plt.show()
š Breed Group Distribution¶
This aggregation pipeline provides a summary count of dog breeds by breed group.
š Pipeline Steps¶
$group- Groups documents by the
breed_groupfield. - Calculates the total number of breeds in each group using
"$sum": 1.
- Groups documents by the
š Result¶
Returns a list of breed groups (e.g., "Sporting", "Toy", "Hound") along with the number of breeds in each group.
This summary helps understand the distribution of breeds across different functional or historical classifications.
pipeline = [
{
"$group": {
"_id": "$breed_group",
"count": {"$sum": 1}
}
}
]
# Execute the aggregation pipeline
results = list(pets_collection.aggregate(pipeline))
df5 = pd.DataFrame(results)
# Display the first 10 results
df5.head(10)
# Extract the labels (breed groups) and sizes (counts)
labels = [doc["_id"] for doc in results if doc["_id"] is not None]
sizes = [doc["count"] for doc in results if doc["_id"] is not None]
# Plot the pie chart
plt.figure(figsize=(8, 8))
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title("Distribution of Dog Breed Groups")
plt.axis('equal') # Equal aspect ratio ensures the pie chart is circular.
plt.show()
š Visualization: Cat Breeds by Geographic Origin¶
This interactive map displays various cat breeds according to their country of origin, using geocoordinates stored in the type_cats collection.
š Steps Involved:¶
MongoDB Query
Retrieves breed data, origin, life span, weight, temperament, and geo-coordinates.Data Cleaning
- Extracts
latandlonfrom the nestedgeocordfield. - Converts
originfrom a list to a readable string format.
- Extracts
Map Visualization (Plotly)
- Each breed is shown as a dot on the map.
- Hovering reveals breed name and country of origin.
- Colored by origin for easy visual grouping.
šŗļø Outcome¶
An interactive scatter map that provides insights into the geographic distribution of cat breeds globally.
import plotly.express as px
db = client["catsdb"]
collection = db["type_cats"]
# 2. Query the collection
cursor = collection.find(
{},
{
"_id": 0,
"type_of_pet": 1,
"breed": 1,
"country_code": 1,
"origin": 1,
"geocord": 1,
"life_span": 1,
"weight": 1,
"temperament": 1
}
)
results = collection.aggregate(pipeline)
for doc in results:
print(doc)
df = pd.DataFrame(list(cursor))
# 3. Flatten geocord into 'lat' and 'lon'
df_geo = pd.json_normalize(df["geocord"])
df["lat"] = df_geo["lat"]
df["lon"] = df_geo["lon"]
# 4. Convert 'origin' from list to simple string
def list_to_str(x):
if isinstance(x, list) and len(x) > 0:
return x[0] # e.g. ["Egypt"] -> "Egypt"
return "Unknown"
df["origin_str"] = df["origin"].apply(list_to_str)
fig = px.scatter_mapbox(
df,
lat="lat",
lon="lon",
hover_name="breed",
hover_data=["origin_str"],
color="origin_str",
zoom=1,
height=600
)
fig.update_layout(
mapbox_style="open-street-map",
title="Cat Breeds by Origin",
title_x=0.5
)
fig.show()
š Origin Distribution of Cat Breeds¶
This aggregation pipeline analyzes how cat breeds are distributed across different countries of origin in the type_cats collection.
𧩠Pipeline Breakdown¶
Group by Origin
Counts how many cat breeds are associated with eachorigin.Calculate Total
Gathers all origin counts into an array and computes the overall total.Unwind Origins
Flattens the array to work with individual origin entries.Project Final Output
Displays:origincountof breeds from that originproportionrelative to the total number of breeds
Sort by Proportion
Orders the results from the most common to the least represented origins.
š Result¶
A ranked list of cat breed origins, showing their share of the total breed count, useful for visualizations like bar or pie charts.
import plotly.express as px
db = client["catsdb"]
collection = db["type_cats"]
pipeline = [
# Group by "origin" and count the number of cats per origin
{
"$group": {
"_id": "$origin",
"count": {"$sum": 1}
}
},
# Compute the total count and push each origin's count into an array
{
"$group": {
"_id": None,
"origins": {"$push": {"origin": "$_id", "count": "$count"}},
"total": {"$sum": "$count"}
}
},
# Unwind the origins array to get individual documents per origin
{
"$unwind": "$origins"
},
# Project the results: show the origin, count, and proportion (count divided by total)
{
"$project": {
"_id": 0,
"origin": "$origins.origin",
"count": "$origins.count",
"proportion": {"$divide": ["$origins.count", "$total"]}
}
},
# Sort the results by proportion in descending order
{
"$sort": {"proportion": -1}
},
# Limit to top 10
{
"$limit": 10
}
]
# Run the pipeline and convert the results to a list of dictionaries
data = list(collection.aggregate(pipeline))
# Convert the results into a pandas DataFrame
df = pd.DataFrame(data)
# Convert any list-type values in 'origin' to a comma-separated string
df['origin'] = df['origin'].apply(lambda x: ', '.join(x) if isinstance(x, list) else x)
# Create an interactive treemap using Plotly Express
fig = px.treemap(
df,
path=['origin'], # Use origin as the hierarchical path
values='count', # Size corresponds to the count
title='Cats Distribution by Origin'
)
# Update traces to show percentage on the plot using the computed percentEntry
fig.update_traces(
texttemplate='%{label}<br>%{value} cats<br>%{percentEntry:.1%}',
)
# Display the plot
fig.show()
š±š¶ Top 10 Longest-Living Cat and Dog Breeds¶
These pipelines to extract and analyze the average life span of cat and dog breeds.
- Extracts numeric values using regex
- Computes the average lifespan for each breed
- Sorts by longest-living breeds
- Displays the Top 10 cat breeds and Top 10 dog breeds
Useful for identifying breeds with the longest expected lifespans!
# === CATS PIPELINE ===
cat_collection = client["catsdb"]["type_cats"]
cat_pipeline = [
{ "$project": {
"breed": 1,
"life_span": 1,
"type_of_pet": { "$literal": "cat" }
}},
{ "$addFields": {
"digits": {
"$regexFindAll": {
"input": { "$replaceAll": { "input": "$life_span", "find": "to", "replacement": "-" } },
"regex": "\\d+"
}
}
}},
{ "$addFields": {
"numbers": {
"$map": {
"input": "$digits",
"as": "d",
"in": { "$toInt": "$$d.match" }
}
}
}},
{ "$addFields": {
"avgLifeSpan": {
"$cond": [
{ "$eq": [ { "$size": "$numbers" }, 2 ] },
{ "$floor": { "$avg": "$numbers" } },
{ "$arrayElemAt": [ "$numbers", 0 ] }
]
}
}},
{ "$sort": { "avgLifeSpan": -1 } },
{ "$limit": 10 }
]
top_10_cats = list(cat_collection.aggregate(cat_pipeline))
# === DOGS PIPELINE ===
dog_collection = client["dogsdb"]["type_dogs"]
dog_pipeline = [
{ "$project": {
"breed": 1,
"life_span": 1,
"type_of_pet": { "$literal": "dog" }
}},
{ "$addFields": {
"digits": {
"$regexFindAll": {
"input": { "$replaceAll": { "input": "$life_span", "find": "to", "replacement": "-" } },
"regex": "\\d+"
}
}
}},
{ "$addFields": {
"numbers": {
"$map": {
"input": "$digits",
"as": "d",
"in": { "$toInt": "$$d.match" }
}
}
}},
{ "$addFields": {
"avgLifeSpan": {
"$cond": [
{ "$eq": [ { "$size": "$numbers" }, 2 ] },
{ "$floor": { "$avg": "$numbers" } },
{ "$arrayElemAt": [ "$numbers", 0 ] }
]
}
}},
{ "$sort": { "avgLifeSpan": -1 } },
{ "$limit": 10 }
]
top_10_dogs = list(dog_collection.aggregate(dog_pipeline))
# === COMBINE & DISPLAY ===
print("\nš± Top 10 Longest-Living Cats:")
for cat in top_10_cats:
print(f"- {cat['breed']}: {cat['avgLifeSpan']} years (raw: {cat.get('life_span')})")
print("\nš¶ Top 10 Longest-Living Dogs:")
for dog in top_10_dogs:
print(f"- {dog['breed']}: {dog['avgLifeSpan']} years (raw: {dog.get('life_span')})")
# OPTIONAL: Combine into one list if needed
# Combine both lists
all_top_pets = top_10_cats + top_10_dogs
# Convert to pandas DataFrame
df_top_pets = pd.DataFrame(all_top_pets)
# Reorder columns if desired
df_top_pets = df_top_pets[["type_of_pet", "breed", "avgLifeSpan", "life_span"]]
# Display the DataFrame
df_top_pets
Conclusion¶
In this project, I explored the use of NoSQL databases and API integrations to efficiently store, retrieve, and analyze unstructured data. Using a NoSQL database gave me the flexibility to work with different types of data without being limited by a fixed schema, which was really useful for handling real world scenarios. I also connected to external APIs to bring in data dynamically, which added a real time component to the project. This combination of NoSQL and APIs helped me build a scalable and flexible data pipeline that could handle both live and batch data. Overall, this experience showed me how powerful and versatile these modern tools can be when used together.
Learning¶
Throughout this project, I gained hands on experience working with NoSQL databases and saw firsthand how they offer more flexibility and scalability than traditional relational databases, especially when working with varied or evolving data. I also learned how to connect and interact with APIs to fetch and update data in real time, which added a dynamic layer to my analysis. This helped me understand how to combine external data sources with local storage in an efficient and practical way. Working through this process improved my ability to design and implement end to end data workflows. These are skills I know will be valuable in future data projects.
!jupyter nbconvert final_project.ipynb --to html \
--TagRemovePreprocessor.enabled=True \
--TagRemovePreprocessor.remove_input_tags='["hide_input"]' \
#--TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'
!jupyter nbconvert final_project.ipynb --to html \
--TagRemovePreprocessor.enabled=True \
--TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'
!jupyter nbconvert final_project.ipynb --to html --TagRemovePreprocessor.enabled=True \
--TagRemovePreprocessor.remove_input_tags='["remove_input"]' \
--TagRemovePreprocessor.remove_single_output_tags='["remove_single_output"]'